spring mvc参数绑定
2016-12-14 22:08
309 查看
spring绑定参数的过程
从客户端请求key/value数据,经过参数绑定,将key/value数据绑定到controller方法的形参上。springmvc中,接收页面提交的数据是通过方法形参来接收,而不是在controller类定义成员变更接收!默认支持的类型
直接在controller方法形参上定义下边类型的对象,就可以使用这些对象,在参数绑定过程中,如果遇到下边类型直接进行绑定。
HttpServletRequest,通过request对象获取请求信息
HttpServletResponse,通过response处理响应信息
HttpSession,通过session对象得到session中存放的对象
Model/ModelMap,model是一个接口,modelMap是一个接口实现 。作用是将model数据填充到request域。
简单类型
当参数类型是java的基本数据类型时,提交到controller的name和接收方法的形参名称一致就接收到数据。如:@RequestMapping(value="/addItems", method={RequestMethod.POST, RequestMethod.GET}) public String addItems(HttpServletRequest request, Model model, String itemsName) throws Exception { System.out.println("商品名称:" + itemsName); return "forward:queryItems"; }
这时候在浏览器输入http://localhost:8080/ssm/items/addItmes?itemsName='Java编程思想',或者请求页面中的链接为:
<a href="items/addItems?itemsName='Thinking In Java'">参数传递</a><br />
后台就会接收到商品名为《Java编程思想》的商品名。其中那个RequesMapping的属性value是对应的url,method是规定该方法接收的请求类型,这里既运行使用post请求,同事也允许get请求。
如果request传入的参数和形参的名称不一致,需要使用@RequestParam进行绑定才能映射成功。
@RequestMapping(value="/addItems", method={RequestMethod.POST, RequestMethod.GET}) public String addItems(HttpServletRequest request, Model model, @RequestParam(value="bookName", required=false) String itemsName) throws Exception { System.out.println("商品名称:" + itemsName); return null; }
<a href="items/addItems?bookName='Thinking In Java'">参数传递</a><br />
可以看到请求的参数名称叫做:bookName,而方法的形参名称叫做:itemsName,但是加上这一句@RequestParam(value="bookName", required=false)之后,请求参数可以参观的映射到形参。
如果不使用@RequestParam,要求request传入参数名称和controller方法的形参名称一致,方可绑定成功;如果使用@RequestParam,不用限制request传入参数名称和controller方法的形参名称一致。通过required属性指定参数是否必须要传入,如果设置为true,没有传入参数,报下边错误:
pojo绑定
当页面中input的name和controller的pojo形参中的属性名称一致,将页面中数据绑定到pojo。我的pojo定义如下:
public class Items { private Integer id; private String name; private Float price; private String pic; private Date createtime; private String detail; //getter/setter }
jsp:页面定义:
<form action="items/addItems" method="post"> <table width="50%" border="1px"> <tbody> <tr> <td>商品名称</td> <td><input type="text" name="name"/></td> </tr> <tr> <td>商品价格</td> <td><input type="text" name="price" /></td> </tr> <tr> <td colspan="2"><input type="submit" value="添加" /></td> </tr> </tbody> </table> </form>
先测一测简单的数据类型,商品名和商品价格,因为这两种类型都是简单的数据类型,Date类型接下来再解决。
controller的接收方法
@RequestMapping("/addItems") public String addItems(HttpServletRequest request, Model model, Items items) throws Exception { System.out.println("商品名:" + items.getName()); System.out.println("商品价格:" + items.getPrice()); return null; }
这里可以看到,添加商品的jsp页面中,商品的input的name="name",这个值将映射成为items对象的name属性,input的name="price"商品价格的值会映射到items对象的price这个属性里边。
再来测试另外几种数据类型,再定义一个java bean:Student。
public class Student { /* * id */ private int id; /** * 姓名 */ private String name; /** * 是否成年 */ private boolean adaut; /** * 生日 */ private Date birthday; /** * 身高 */ private float hight; //getter/setter }
提交表单的jsp页面如下:
<form action="items/addStudent" method="post"> <table width="50%" border="1px"> <tbody> <tr> <td>id</td> <td><input type="text" name="id"/></td> </tr> <tr> <td>姓名</td> <td><input type="text" name="name" /></td> </tr> <tr> <td>是否成年</td> <td> <input type="radio" name="adaut" value="true" checked>是 <input type="radio" name="adaut" value="false">否 </td> </tr> <tr> <td>生日</td> <td><input type="text" name="birthday" /></td> </tr> <tr> <td>身高</td> <td><input type="text" name="hight" /></td> </tr> <tr> <td colspan="2"><input type="submit" value="添加" /></td> </tr> </tbody> </table> </form>
在这个JavaBean的属性中有日期类型,需要自定义参数绑定。将请求日期数据串传成 日期类型,要转换的日期类型和pojo中日期属性的类型保持一致,需要向处理器适配器中注入自定义的参数绑定组件。
自定义日期类型绑定
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import org.springframework.core.convert.converter.Converter; public class CustomDateConverter implements Converter<String, Date> { public Date convert(String source) { //实现将日期串转成日期类型(格式是yyyy-MM-dd HH:mm:ss) SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { return sdf.parse(source); } catch (ParseException e) { e.printStackTrace(); } return null; } }
在配置文件中配置:
<mvc:annotation-driven conversion-service="conversionService" /> <!-- 自定义参数绑定 --> <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <!-- 转换器 --> <property name="converters"> <list> <!-- 日期转换类型 --> <bean class="com.shizongger.ssm.model.CustomDateConverter" /> </list> </property> </bean>
如此这般,jsp页面的input输入框中,日期格式如:2016-12-12 21:59:00的字符串变会转换成Date的日期格式。是否成年的boolean值也会传递到adaut属性中。
包装类型pojo参数绑定
需求:商品查询controller方法中实现商品查询条件传入。
实现方法:
在形参中 添加HttpServletRequest request参数,通过request接收查询条件参数。
在形参中让包装类型的pojo接收查询条件参数。
分析:
页面传参数的特点:复杂,多样性。条件包括 :用户账号、商品编号、订单信息。如果将用户账号、商品编号、订单信息等放在简单pojo(属性是简单类型)中,pojo类属性比较多,比较乱。建议使用包装类型的pojo,pojo中属性是pojo。
定义一个查询的java bean QueryVo,所有将要查询的条件都将由这个vo接收。
public class QueryVo { private Items items; private Student student; public Items getItems() { return items; } public void setItems(Items items) { this.items = items; } public Student getStudent() { return student; } public void setStudent(Student student) { this.student = student; } }
Items和Student定义如上所述,这个vo定义了两个属性items商品和student用户(里面student就是用户),两者都有一个共同的属性名:name,items商品中有一个属性名name代表商品名称,student有一个属性名name代表用户名称,这个案例将展示如果分别向这个不同的name属性传递值。
jsp页面代码:
<form action="queryItems" method="post"> <table border="1px" width="80%"> <tr> <td>商品名:<input type="text" name="items.name" /></td> <td>商品价格:<input type="text" name="items.price" /></td> <td>商品详情:<input type="text" name="items.detail" /></td> <td>下单用户:<input type="text" name="student.name" /></td> <td><input type="submit" value="查询" /></td> </tr> </table> </form>
controller代码:
//商品查询 @RequestMapping("/queryItems") public ModelAndView queryItems(HttpServletRequest request, QueryVo queryVo) throws Exception{ if(null != queryVo && null != queryVo.getItems() && null != queryVo.getStudent()) { System.out.println("前端传递过来的查询条件:"); System.out.println("商品名称:" + queryVo.getItems().getName() + " 商品价格:" + queryVo.getItems().getPrice() + " 商品详情:" + queryVo.getItems().getDetail() + " 下单用户:" + queryVo.getStudent().getName() ); } }
在input的name属性中,name值与queryVo属性的属性名对应,才能映射成功。
集合类型的绑定
数组类型绑定
需求:商品批量删除,用户在页面选择多个商品,批量删除。
分析:
在批量删除需求中,如果能够一次性拿到jsp页面中复选框选中的内容那好办了。所以我们可以将页面选择(多选)的商品id,传到controller方法的形参,方法形参使用数组接收页面请求的多个商品id。
controller方法定义:
@RequestMapping("/deleteItems") public String deleteItems(HttpServletRequest request, Integer[] itemsIds) { for(int i = 0; i < itemsIds.length; i++) { System.out.println("要删除的id:" + itemsIds[i]); } return null; }
jsp页面定义:
<form id="itemsTalbe"> <table border="1px" width="80%"> <thead> <tr><td>删除</td><th>序列</th><th>商品名称</th><th>商品详情</th><th>商品价格</th><th>订单创建时间</th><th>修改</th></tr> </thead> <tbody> <c:forEach items="${itemsList }" var="items" varStatus="status"> <tr> <td><input type="checkbox" name="itemsIds" value="${items.id }" /></td> <td>${status.count }</td> <td>${items.name }</td> <td>${items.detail }</td> <td>${items.price }</td> <td>${items.createtime }</td> <td><a href="editItems?id=${items.id }">修改</a></td> </tr> </c:forEach> <tr> <td colspan="7"><input type="submit" value="批量删除" onclick="batchDelete()"/></td> </tr> </tbody> </table> </form>
js代码:
function batchDelete() { var form = document.getElementById("itemsTalbe"); form.action ="${pageContext.servletContext.contextPath }/items/deleteItems"; form.submit(); }
在jsp页面中,用jstl迭代输出表格中每一行的记录内容。最重要的是每一行的第一个td的内容:
<td><input type="checkbox" name="itemsIds" value="${items.id }" /></td>
name属性等于itemsIds正是controller接收参数Interger数组的名称。
list绑定
通常在需要批量提交数据时,将提交的数据绑定到list< pojo>中,比如:成绩录入(录入多门课成绩,批量提交),本例子需求:批量商品修改,在页面输入多个商品信息,将多个商品信息提交到controller方法中。
在上诉的请求vo中,再添加属性:
private List<Items> itemsList;
完整的vo如下:
public class QueryVo { private Items items; private Student student; private List<Items> itemsList; public List<Items> getItemsList() { return itemsList; } public void setItemsList(List<Items> itemsList) { this.itemsList = itemsList; } public Items getItems() { return items; } public void setItems(Items items) { this.items = items; } public Student getStudent() { return student; } public void setStudent(Student student) { this.student = student; } }
jsp页面:
springmvc和struts2的区别
springmvc基于方法开发的,struts2基于类开发的。springmvc将url和controller方法映射。映射成功后springmvc生成一个Handler对象,对象中只包括了一个method。方法执行结束,形参数据销毁。springmvc的controller开发类似service开发。springmvc可以进行单例开发,并且建议使用单例开发,struts2通过类的成员变量接收参数,无法使用单例,只能使用多例。
经过实际测试,struts2速度慢,在于使用struts标签,如果使用struts建议使用jstl。
参考资料:<传智播客_Springmvc+Mybatis由浅入深之spring mvc>
相关文章推荐
- Java 无法跨域问题(No 'Access-Control-Allow-Origin'..)
- 各Spring-Boot-Starters介绍
- java--数据类型和运算符备忘知识点
- spring mvc参数绑定
- 利用阿里大于发送短信验证码(java)
- Struts的类型转换
- java小测试-A+B>C
- Eclipse中.setting目录下文件介绍
- spring,struts2,mybatis命名空间编辑
- Spring学习03--其他特性(减少配置、自动装配、scope作用域,延迟初始化)
- Dalvik虚拟机java方法执行流程和Method结构体分析
- JAVA中String为final修饰类
- eclipse安装完maven后,打开报错 Eclipse is running in a JRE, but a JDK is required
- Java变量类型
- RxJava操作符系列三
- Java——泛型
- Java语法教程
- 【转载】 Java 7之基础 - 强引用、弱引用、软引用、虚引用
- Java类加载基本过程
- Java 8 中 Date与LocalDateTime、LocalDate、LocalTime互转