SpringMVC参数绑定
一、参数绑定原理
1、什么是参数绑定?
前台页面通常会有数据提交给后台进行处理(如提交表单),参数绑定的作用就是将这些数据正确地交给Controller进行处理。
2、参数绑定的实现
在springMVC中提交请求的参数是通过方法的形参来接收的,从客户端请求的key/value数据,经过参数绑定,将key/value数据绑定到Controller的形参上,然后Controller就可以直接使用该形参了。
二、参数绑定支持
1、默认支持的类型
SpringMVC 有支持的默认参数类型,我们直接在形参上给出这些默认类型的声明,就能直接使用了。如下:
HttpServletRequest 类型
HttpServletResponse 类型
HttpSession 类型
Model/ModelMap 类型
Controller:
@RequestMapping("/default") public String index(HttpServletRequest request, HttpServletResponse response, HttpSession session, Model model, ModelMap modelMap) { request.setAttribute("request", "request类型"); session.setAttribute("session", "session类型"); model.addAttribute("model", "model类型"); modelMap.addAttribute("modelMap", "modelMap类型"); return "success"; }
success.jsp
<body> ${request} ${session} ${model} ${modelMap} </body>
结果:
2、基本数据类型(对应的包装类型)绑定
int(Integer)、short(Short)、long(Long)、float(Float)、
double(Double)、byte(Byte)、char(Character)、boolean(Boolean)、String
controller:
// springmvc可以直接接收基本数据类型和String,可以自动进行类型转换 // Controller方法接收的参数的变量名称必须等于页面中input标签中name属性值 @RequestMapping("/updateitem1") public String update1(Integer id, String name, Float price, String detail) throws Exception { Items items = new Items(); items.setId(id); items.setName(name); items.setPrice(price); items.setDetail(detail); itemsService.updateItems(items); return "success"; }
editForm.jsp
<form id="itemForm" action="${pageContext.request.contextPath }/updateitem1.action" method="post"> <input type="hidden" name="id" value="${item.id }" /> 修改商品信息: <table width="100%" border=1> <tr> <td>商品名称</td> <td><input type="text" name="name" value="${item.name }" /></td> </tr> <tr> <td>商品价格</td> <td><input type="text" name="price" value="${item.price }" /></td> </tr> <tr> <td>商品简介</td> <td><textarea rows="3" cols="30" name="detail">${item.detail }</textarea> </td> </tr> <tr> <td colspan="2" align="center"><input type="submit" value="提交" /> </td> </tr> </table> </form>
注意:表单中input的name值和Controller方法里的参数变量名保持一致,就能完成数据绑定。当然也可以不一致,不一致就必须使用@RequestParam 注解来完成。例如:
@RequestMapping("/updateitem1") public String update1(Integer id, @RequestParam("name")String username, Float price, String detail) throws Exception { // code }
使用注解 @RequestParam ,我们可以使用任意形参,但是注解里面的 value 属性值要和表单的name属性值一样。
3、实体类(POJO)类型绑定
SpringMVC提供了一个更加智能、更少代码的绑定方式,就是实体类绑定。相比上面的一种方式,可以不需在Controller中使用set方法设置实体类属性。要求:前台页面中如input中name属性值必须等于实体类对应的属性。
实体类User.java
package cn.itheima.pojo; import java.util.Date; public class User { private Integer id; private String username; private Date birthday; private String sex; private String address; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username == null ? null : username.trim(); } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex == null ? null : sex.trim(); } public String getAddress() { return address; } public void setAddress(String address) { this.address = address == null ? null : address.trim(); } }
页面editItem.jsp
<form id="itemForm" action="${pageContext.request.contextPath }/updateitem2.action" method="post"> <input type="hidden" name="id" value="${item.id }" /> 修改商品信息: <table width="100%" border=1> <tr> <td>商品名称</td> <td><input type="text" name="name" value="${item.name }" /></td> </tr> <tr> <td>商品价格</td> <td><input type="text" name="price" value="${item.price }" /></td> </tr> <tr> <td>商品简介</td> <td><textarea rows="3" cols="30" name="detail">${item.detail }</textarea> </td> </tr> <tr> <td colspan="2" align="center"><input type="submit" value="提交" /> </td> </tr> </table> </form>
Controller:
// springmvc可以直接接收pojo类型,这样比上面接收基本类型更快捷,要求input标签中name属性值必须等于pojo中属性名称 @RequestMapping("/updateitem2") public String update2(Items items) throws Exception { itemsService.updateItems(items); return "success"; }
注:实体类User中有个属性为birthday,类型为Date,页面中input框传入的birthday是String类型,传递给Controller必须转换为Date。这时候必须使用“自定义转换器”。
如editItem.jsp中表单里增加一个商品生产日期:
<form id="itemForm" action="${pageContext.request.contextPath }/updateitem2.action" method="post"> <input type="hidden" name="id" value="${item.id }" /> 修改商品信息: <table width="100%" border=1> <tr> <td>商品名称</td> <td><input type="text" name="name" value="${item.name }" /></td> </tr> <tr> <td>商品价格</td> <td><input type="text" name="price" value="${item.price }" /></td> </tr> <tr> <td>商品生产日期</td> <td><input type="text" name="createtime" value="<fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/>" /></td> </tr> <tr> <td>商品简介</td> <td><textarea rows="3" cols="30" name="detail">${item.detail }</textarea> </td> </tr> <tr> <td colspan="2" align="center"><input type="submit" value="提交" /> </td> </tr> </table> </form>
自定义转换器:
package cn.itheima.controller.converter; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import org.springframework.core.convert.converter.Converter; /** * S - source:源 * T - target:目标 * @author Administrator * */ public class CustomGlobalStrToDateConverter implements Converter<String, Date> { @Override public Date convert(String source) { try { Date date = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse(source); return date; } catch (ParseException e) { e.printStackTrace(); } return null; } }
在SpringMvc.xml中配置自定义转换器
<!-- 注解驱动:自动配置最新版的处理器映射器和处理器适配器 --> <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven> <!-- 注:一定要将自定义的转换器配置到注解驱动上 --> <!-- 转换器配置 --> <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="converters"> <set> <bean class="cn.itheima.controller.converter.CustomGlobalStrToDateConverter"/> </set> </property> </bean>
4、数组类型参数绑定
使用场景:有时候对于一些数据需要批量处理,如批量删除,这时候需要用到数组类型的绑定。
QueryVO.java
package cn.itheima.vo; import java.util.List; import cn.itheima.pojo.Items; public class QueryVO {// 批量删除使用 private Integer[] ids;public Integer[] getIds() { return ids; } public void setIds(Integer[] ids) { this.ids = ids; } }
itemList.jap
<form action="${pageContext.request.contextPath }/delAll.action" method="post"> 查询条件: <table width="100%" border=1> <tr> <td>商品名称:<input type="text" name="items.name"></td> <td>商品价格:<input type="text" name="items.price"></td> <td><input type="submit" value="批量删除"/></td> </tr> </table> 商品列表: <table width="100%" border=1> <tr> <td></td> <td>商品名称</td> <td>商品价格</td> <td>生产日期</td> <td>商品描述</td> <td>操作</td> </tr> <c:forEach items="${itemList}" var="item"> <tr> <!-- name属性值要和QueryVO中接收的属性名称一致 --> <td> <input type="checkbox" name="ids" value="${item.id}"/> </td> <td>${item.name}</td> <td>${item.price}</td> <td><fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/></td> <td>${item.detail}</td> <td><a href="${pageContext.request.contextPath }/itemEdit.action?id=${item.id}">修改</a></td> </tr> </c:forEach> </table> </form>
Controller
@RequestMapping("/delAll") public String delAll(QueryVO vo) throws Exception { // 如果批量删除,一堆input框,那么可以提交数组 System.out.println(vo); return ""; }
5、List类型参数绑定
使用场景:批量修改Items信息
QueryVO.java
package cn.itheima.vo; import java.util.List; import cn.itheima.pojo.Items; public class QueryVO {// 批量修改操作 private List<Items> itemsList; public List<Items> getItemsList() { return itemsList; } public void setItemsList(List<Items> itemsList) { this.itemsList = itemsList; } }
Controller
@RequestMapping("/updateAll") public String updateAll(QueryVO vo) throws Exception { System.out.println(vo); return ""; }
itemList.jsp
<c:forEach items="${itemList}" var="item" varStatus="status"> <tr> <!-- name属性值要和QueryVO中接收的属性名称一致 --> <td> <input type="checkbox" name="ids" value="${item.id}"/> <input type="hidden" name="itemsList[${status.index}].id" value="${item.id}"/> </td> <td><input type="text" name="itemsList[${status.index}].name" value="${item.name}"/></td> <td><input type="text" name="itemsList[${status.index}].price" value="${item.price}"/></td> <td><input type="text" name="itemsList[${status.index}].createtime" value="<fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/>"/></td> <td><input type="text" name="itemsList[${status.index}].detail" value="${item.detail}"/></td> <td><a href="${pageContext.request.contextPath }/itemEdit.action?id=${item.id}">修改</a></td> </tr> </c:forEach>