十、SpringMVC注解开发之参数绑定

简单参数绑定

Spring参数绑定过程

SpringMVC中,从客户端请求key/value数据,通过参数绑定,将key/value数据绑定到controller方法的形参上。而不是在controller类定义成员变量接收。java

默认支持的类型

直接在controller方法形参上定义下边类型的对象,就能够使用这些对象。spring

  • HttpServletRequest:经过request对象获取请求信息
  • HttpServletResponse:经过response处理响应信息
  • HttpSession:经过session对象获得session中存放的对象
  • Model/ModelMap:model是一个接口,modelMap是一个接口实现。做用:将model数据填充到request域。

简单类型

经过@RequestParam对简单类型的参数进行绑定,不用限制request传入参数名称和controller方法的形参名称一致。若是不使用@RequestParam,要求request传入参数名称和controller方法的形参名称一致,也可绑定成功。数组

经过required属性指定参数是否必需要传入,若是设置为true,没有传入参数,报错误。session

经过defaultValue能够设置默认值,若是id参数没有传入,将默认值和形参绑定。mvc

@RequestMapping(value="/editItems",method={RequestMethod.POST,RequestMethod.GET})
public String editItems(Model model,@RequestParam(value="id",required=true,defaultValue =0) Integer items_id) {

pojo绑定

页面中input的name和controller的pojo形参中的属性名称一致,将页面中数据绑定到pojo。app

注意:这里只是要求name和形参的属性名一致,而不是要求和形参的名称一致,这点不要混淆了,框架会进入形参内部自动匹配pojo类的属性名。(应该是用反射实现的)框架

页面定义:jsp

<table width="100%" border=1>
<tr>
	<td>商品名称</td>
	<td><input type="text" name="name" value="${itemsCustom.name}"/></td>
</tr>
<tr>
	<td>商品价格</td>
	<td><input type="text" name="price" value="${itemsCustom.price}"/></td>
</tr>

controller的pojo形参的定义:ui

public class Items {
    private Integer id;

    private String name;

    private Float price;

    private String pic;

    private Date createtime;

    private String detail;
}

自定义参数绑定实现日期类型绑定

对于controller形参中pojo对象,若是属性中有日期类型,须要自定义参数绑定。code

将请求日期数据串转成日期类型,要转换的日期类型和pojo中日期属性的类型保持一致。本文示例中,自定义参数绑定将日期串转成java.util.Date类型。须要向处理器适配器中注入自定义的参数绑定组件。

  • 自定义日期类型绑定
public class CustomDateConverter implements Converter<String,Date>{
    public Date convert(String s) {
        //实现 将日期串转成日期类型(格式是yyyy-MM-dd HH:mm:ss)
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            //转成直接返回
            return simpleDateFormat.parse(s);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //若是参数绑定失败返回null
        return null;
    }
}
  • 配置方式
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
<!-- 自定义参数绑定 -->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
    <!-- 转换器 -->
    <property name="converters">
        <list>
            <!-- 日期类型转换 -->
            <bean class="com.iot.learnssm.firstssm.controller.converter.CustomDateConverter"/>
        </list>
    </property>
</bean>

包装类型参数绑定

实现方法

  • 第一种方法:在形参中添加HttpServletRequest request参数,经过request接收查询条件参数。
  • 第二种方法:在形参中让包装类型的pojo接收查询条件参数。

分析:

页面传参数的特色:复杂,多样性。条件包括:用户帐号、商品编号、订单信息。。。

若是将用户帐号、商品编号、订单信息等放在简单pojo(属性是简单类型)中,pojo类属性比较多,比较乱。建议使用包装类型的pojo,pojo中属性是pojo。

页面参数和controller方法形参定义

  • 页面参数:

商品名称:<input name="itemsCustom.name" />

注意:itemsCustom和包装pojo中的属性名一致便可。

  • controller方法形参:
public ModelAndView queryItems(HttpServletRequest request, ItemsQueryVo itemsQueryVo)
  • 包装类ItemsQueryVo中部分属性:
public class ItemsQueryVo {

    //商品信息
    private Items items;

    //为了系统 可扩展性,对原始生成的po进行扩展
    private ItemsCustom itemsCustom;
}

可见,ItemsQueryVo中属性itemsCustom和页面参数中一致

集合类型参数绑定

数组绑定

将页面选择(多选)的商品id,传到controller方法的形参,方法形参使用数组接收页面请求的多个商品id。

  • controller方法定义:
// 批量删除 商品信息
@RequestMapping("/deleteItems")
public String deleteItems(Integer[] items_id)
  • 页面定义:
<c:forEach items="${itemsList}" var="item">
<tr>
    <td><input type="checkbox" name="items_id" 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}/items/editItems.action?id=${item.id}">修改</a></td>
</tr>
</c:forEach>

List绑定

使用List接收页面提交的批量数据,经过包装pojo接收,在包装pojo中定义list<pojo>属性

public class ItemsQueryVo {

    //商品信息
    private Items items;

    //为了系统 可扩展性,对原始生成的po进行扩展
    private ItemsCustom itemsCustom;

    //批量商品信息
    private List<ItemsCustom> itemsList;
}
// 批量修改商品提交
// 经过ItemsQueryVo接收批量提交的商品信息,将商品信息存储到itemsQueryVo中itemsList属性中。
@RequestMapping("/editItemsAllSubmit")
public String editItemsAllSubmit(ItemsQueryVo itemsQueryVo) throws Exception {
    return "success";
}
  • 页面定义:
<c:forEach items="${itemsList}" var="item" varStatus="status">
    <tr>
        <td><input name="itemsList[${status.index}].name" value="${item.name}"/></td>
        <td><input name="itemsList[${status.index}].price" value="${item.price}"/></td>
        <td><input name="itemsList[${status.index}].createtime" value="<fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/>"/></td>
        <td><input name="itemsList[${status.index}].detail" value="${item.detail}"/></td>
    </tr>
</c:forEach>

name的格式:

对应包装pojo中的list类型属性名[下标(从0开始)].包装pojo中List类型的属性中pojo的属性名

例子:"name="itemsList[${status.index }].price"

能够和包装类型的参数绑定概括对比一下,其实就是在包装类的pojo基础上多了个下标。只不过包装类参数绑定时,要和包装pojo中的pojo类性的属性名一致,而list参数绑定时,要和包装pojo中的list类型的属性名一致。

Map绑定

经过在包装pojo中定义map类型属性,action使用包装对象接收。

  • 包装类中定义Map对象以下:
Public class QueryVo {
	private Map<String, Object> itemInfo = new HashMap<String, Object>();
}
  • 页面定义以下:
<tr>
    <td>学生信息:</td>
    <td>
    姓名:<inputtype="text"name="itemInfo['name']"/>
    年龄:<inputtype="text"name="itemInfo['price']"/>
    .. .. ..
    </td>
</tr>
  • Contrller方法定义以下:
public String useraddsubmit(Model model,QueryVo queryVo)throws Exception{
	System.out.println(queryVo.getStudentinfo());
}
相关文章
相关标签/搜索