springMVC参数绑定

默认支持的参数类型

处理器形参中添加如下类型的参数处理注解适配器会默认识别并进行赋值。
1 HttpServletRequest
通过 request 对象获取请求信息
2 HttpServletResponse
通过 response 处理响应信息
3 HttpSession
通过 session 对象得到 session 中存放的对象
4 Model
通过 model 向页面传递数据,如下:
// 调用 service 查询商品信息
Items item = itemService .findItemById(id);
model .addAttribute("item", item);
页面通过 ${ item .XXXX} 获取 item 对象的属性值。
model也可以通过modelMap或map将数据传到页面(这是因为底层就是这个类型,具体可以看看底层代码)。

参数绑定介绍

         注解适配器对RequestMapping 标记的方法进行适配,对方法中的形参会进行参数绑定, 早期 springmvc 采用 PropertyEditor (属性编辑器)进行参数绑定将 request 请求的参数绑定到方法形参上, 3.X之后springmvc就开始使用Converter进行参数绑定。

1 @RequestParam: 用于绑定单个请求参数。

             value 参数名字,即入参的请求参数名字,如value= item_id 表示请求的参数区中的名字为 item_id 的参数的值将传入;
注意:如果请求参数中没有 item_id 将跑出异常: HTTP Status 500 - Required Integer parameter 'item_id' is not present
           required 是否必须,默认是 true ,表示请求中一定要有相应的参数,否则将报; TTP Status 400 - Required Integer parameter 'XXXX' is not present
            defaultValue 默认值,表示如果请求中没有同名参数时的默认值( 即使 required=true 也可以不传 item_id 参数值

定义如下:
public String editItem(@RequestParam(value="item_id",required=true) String id) {
 
}
如果request 请求的参数名和controller 方法的形参数名称一致,适配器自动进行参数绑定(不需要手动进行绑定了)。
如果不一致可以通过@RequestParam 指定request 请求的参数名绑定到哪个方法形参上。

简单类型

当请求的参数名称和处理器形参名称一致时会将请求参数与形参进行绑定。
整型
public String editItem(Model model,Integer id) throws Exception

字符串
     例子略
单精度 / 双精度
     例子略
布尔型
     处理器方法:
    public String editItem(Model model,Integer id,Boolean status) throws Exception
请求url
http://localhost:8080/springmvc_mybatis/item/editItem.action?id=2&status=false
说明:对于布尔类型的参数,请求的参数值为 true false
需要注意的是,如果Controller方法参数中定义的是基本数据类型,但是从页面提交过来的数据为null或者”"的话,会出现数据转换的异常。也就是必须保证表单传递过来的数据不能为null或”",所以,在开发过程中,对可能为空的数据,最好将参数数据类型定义成包装类型,具体参见下面的例子。
 @RequestMapping("saysth.do" )
public void test(Integer count) { }
}
表单代码:
< form action ="saysth.do" method ="post" > < input name ="count" value ="10" type ="text" />
......
</ form >
和基本数据类型基本一样,不同之处在于,表单传递过来的数据可以为null或”",以上面代码为例,如果表单中 count 为”"或者表单中无 count 这个input,那么,Controller方法参数中的 count 值则为null。
 


简单 pojo
简单pojo 类型只包括简单类型的属性。
pojo对象中的属性名与传递进来的属性名对应,如果传进来的参数名称和对象中的属性名称一致则将参数值设置在pojo对象中。
页面定义如下;
<input type="text" name=" name "/>
<input type="text" name=" price "/>
Contrller 方法定义如下:
@RequestMapping ( "/editItemSubmit" )
    public String editItemSubmit(Items items) throws Exception{
    System.out.println(items);
请求的参数名称和pojo的属性名称一致,会自动将请求参数赋值给pojo的属性。

包装 pojo
问题:
如果 controller 方法形参中有多个 pojo pojo 中有重复的属性,使用简单 pojo 绑定无法有针对性的绑定,
比如:方法形参有 items User pojo 同时存在 name 属性,从 http 请求过程的 name 无法有针对性的绑定到 items user
 
这个时候需要将pojo对象作为一个包装对象的属性,action中以该包装对象作为形参。
 
包装对象定义( 包装的 pojo 里边包括了 pojo 如下:
Public class QueryVo {
private Items items ;
 
}
页面定义:
<input type="text" name=" items. name" />
<input type="text" name=" items. price" />
Controller 方法定义如下:
public String useraddsubmit(Model model, QueryVo   queryVo)throws Exception{
System.out.println(queryVo.getItems());


数组
页面定义如下:
页面选中多个checkboxcontroller方法传递
<input type="checkbox" name="item_id" value="001"/>
<input type="checkbox" name="item_id" value="002"/>
<input type="checkbox" name="item_id" value="002"/>
 
传递到controller方法中的格式是:001,002,003
Controller 方法中可以用String[]接收,定义如下:
public String deleteitem(String[] item_id)throws Exception{
        System.out.println(item_id);

 List绑定:
List需要绑定在对象上,而不能直接写在Controller方法的参数中。
Model代码:
public class User {
    private String firstName;
    private String lastName;
}
public class UserListForm {
    private List<User> users;
}
Controller代码:
@RequestMapping("saysth.do" )
public void test(UserListForm userForm) {
          for (User user : userForm.getUsers()) { System.out.println(user.getFirstName() 
System.out.println(user.getFirstName() + " - " + user.getLastName()); } }
}
}
表单代码:
< input name ="users[0].firstName" value ="aaa" />
< input name ="users[0].lastName" value ="bbb" />
< input name ="users[1].firstName" value ="ccc" />
< input name ="users[1].lastName" value ="ddd" />
在表单中需要指定List的下标。值得一提的是,Spring会创建一个以最大下标值为size的List对象,所以,如果表单中有动态添加行、删除行的情况,就需要特别注意,譬如一个表格,用户在使用过程中经过多次删除行、增加行的操作之后,下标值就会与实际大小不一致,这时候,List中的对象,只有在表单中对应有下标的那些才会有值,否则会为null,看个例子:
表单代码:
< input name ="users[0].firstName" value ="aaa" />
< input name ="users[0].lastName" value ="bbb" />
< input name ="users[1].firstName" value ="ccc" />
< input name ="users[1].lastName" value ="ddd" />
< input name ="users[20].firstName" value ="eee" />
< input name ="users[20].lastName" value ="fff" />
这个时候,Controller中的userForm.getUsers()获取到List的size为21,而且这21个User对象都不会为null,但是,第2到第19的User对象中的firstName和lastName都为null。打印结果:
aaa - bbb
ccc - ddd
null - null
null - null
......
null - null
null - null
eee - fff
 
6. Set绑定:
Set和List类似,也需要绑定在对象上,而不能直接写在Controller方法的参数中。但是,绑定Set数据时,必须先在Set对象中add相应的数量的模型对象。
Model代码:
public class User {
private String firstName;
private String lastName;
}
public class UserSetForm {
private Set<User> users = new HashSet<User> ();
}
Controller代码:
@RequestMapping("saysth.do" )
public void test(UserSetForm userForm) {
for (User user : userForm.getUsers()) { System.out.println(user.getFirstName()
System.out.println(user.getFirstName() + " - " + user.getLastName()); } }
}
}
表单代码:
< input name ="users[0].firstName" value ="aaa" />
< input name ="users[0].lastName" value ="bbb" />
< input name ="users[1].firstName" value ="ccc" />
< input name ="users[1].lastName" value ="ddd" />
< input name ="users[2].firstName" value ="eee" />
< input name ="users[2].lastName" value ="fff" />
基本和List绑定类似。
需要特别提醒的是,如果最大下标值大于Set的size,则会抛出org.springframework.beans.InvalidPropertyException异常。所以,在使用时有些不便。
 
7. Map绑定:
Map最为灵活,它也需要绑定在对象上,而不能直接写在Controller方法的参数中。
Model代码:
public class User {
private String firstName;
private String lastName;
}
public class UserMapForm {
private Map<String, User> users;
}
Controller代码:
@RequestMapping("saysth.do" )
public void test(UserMapForm userForm) {
for (Map.Entry<String, User> entry : userForm.getUsers().entrySet()) { System.out.println(entry.getKey()
System.out.println(entry.getKey() + ": " + entry.getValue().getFirstName() + " - " +
entry.getValue().getLastName());
}
}
表单代码:
< input name ="users['x'].firstName" value ="aaa" />
< input name ="users['x'].lastName" value ="bbb" />
< input name ="users['y'].firstName" value ="ccc" />
< input name ="users['y'].lastName" value ="ddd" />
< input name ="users['z'].firstName" value ="eee" />
< input name ="users['z'].lastName" value ="fff" />
打印结果:
x: aaa - bbb
y: ccc - ddd
z: eee - fff
 


1.1.1  自定义参数绑定
1.1.1.1 需求
根据业务需求自定义日期格式进行参数绑定。 springmvc 没有提供默认的对日期类型的绑定,需要自定义日期类型的绑定。
1.1.1.2 propertyEditor (了解)
1.1.1.2.1 使用 WebDataBinder
controller 方法中通过 @InitBinder 标识方法为参数绑定方法 ,通过 WebDataBinder 注册属性编辑器,问题是此方法只能在单个 controller 类中注册。
/** 注册属性编辑器 ( 字符串转换为日期 )*/
    @InitBinder
    public void initBinder( WebDataBinder binder) throws Exception {
       binder.registerCustomEditor(Date. class , new CustomDateEditor( new SimpleDateFormat( "yyyy-MM-dd" ), true ));
    }
1.1.1.2.2 使用 WebBindingInitializer
如果想多个 controller 需要共同注册相同的属性编辑器,可以实现 PropertyEditorRegistrar 口,并注入 webBindingInitializer 中。
如下:
编写 CustomPropertyEditor
 
public class CustomPropertyEditor implements PropertyEditorRegistrar {
    public void registerCustomEditors(PropertyEditorRegistry registry) {
       registry.registerCustomEditor(Date. class , new CustomDateEditor( new
               SimpleDateFormat( "yyyy-MM-dd HH-mm-ss" ), true ));
    }
}
 
配置如下:
 
<!-- 注册属性编辑器 -->
    < bean id="customPropertyEditor"class="cn.itcast.ssm.propertyeditor.CustomPropertyEditor"></bean>
<!-- 自定义 webBinder -->
    < bean id="customBinder"
       class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
       < property name="propertyEditorRegistrars">
           < list >
              < ref bean="customPropertyEditor"/>
           </ list >
       </ property >
    </ bean >
<!-- 注解适配器 -->
    < bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
         < property name="webBindingInitializer"ref="customBinder"></property>
    </ bean >

 Converter转换器(架构师掌握)
自定义 Converter
public class CustomDateConverter implements Converter<String, Date> {
    public Date convert(String source) {
       try {
           SimpleDateFormat simpleDateFormat = new SimpleDateFormat( "yyyy-MM-dd HH-mm-ss" );
           return simpleDateFormat.parse(source);
       } catch (Exception e) {
           e.printStackTrace();
       }
       return null ;
    }
}
配置 方式 1
<!-- 注解适配器 -->

    <!-- conversionService -->
    < bean id="conversionService"
    class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
       <!-- 转换器 -->
       < property name="converters">
           < list >
              < bean class="cn.itcast.ssm.controller.converter.CustomDateConverter"/>
           </ list >
       </ property >
    </ bean >
配置 方式 2
< mvc:annotation-driven conversion-service="conversionService">
</ mvc:annotation-driven >
<!-- conversionService -->
    < bean id="conversionService"
    class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
       <!-- 转换器 -->
       < property name="converters">
           < list >
              < bean class="cn.itcast.ssm.controller.converter.CustomDateConverter"/>
           </ list >
       </ property >
    </ bean >



来自为知笔记(Wiz)


你可能感兴趣的:(springMVC参数绑定)