zoukankan      html  css  js  c++  java
  • 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
    说明:对于布尔类型的参数,请求的参数值为truefalse
    需要注意的是,如果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方法形参中有多个pojopojo中有重复的属性,使用简单pojo绑定无法有针对性的绑定,
    比如:方法形参有itemsUserpojo同时存在name属性,从http请求过程的name无法有针对性的绑定到itemsuser
     
    这个时候需要将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.classnew CustomDateEditor(newSimpleDateFormat("yyyy-MM-dd"),true));
        }
    1.1.1.2.2使用WebBindingInitializer
    如果想多个controller需要共同注册相同的属性编辑器,可以实现PropertyEditorRegistrar口,并注入webBindingInitializer中。
    如下:
    编写CustomPropertyEditor
     
    public class CustomPropertyEditorimplements PropertyEditorRegistrar {
        public void registerCustomEditors(PropertyEditorRegistry registry) {
           registry.registerCustomEditor(Date.classnewCustomDateEditor(new
                   SimpleDateFormat("yyyy-MM-dd HH-mm-ss"),true));
        }
    }
     
    配置如下:
     
    <!-- 注册属性编辑器 -->
        <beanid="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 = newSimpleDateFormat("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>
                  <beanclass="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>
                  <beanclass="cn.itcast.ssm.controller.converter.CustomDateConverter"/>
               </list>
           </property>
        </bean>
    老铁,你的--->推荐,--->关注,--->评论--->是我继续写作的动力。
    由于博主能力有限,文中可能存在描述不正确,欢迎指正、补充!
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    (转载)SAPI 包含sphelper.h编译错误解决方案
    C++11标准的智能指针、野指针、内存泄露的理解(日后还会补充,先浅谈自己的理解)
    504. Base 7(LeetCode)
    242. Valid Anagram(LeetCode)
    169. Majority Element(LeetCode)
    100. Same Tree(LeetCode)
    171. Excel Sheet Column Number(LeetCode)
    168. Excel Sheet Column Title(LeetCode)
    122.Best Time to Buy and Sell Stock II(LeetCode)
    404. Sum of Left Leaves(LeetCode)
  • 原文地址:https://www.cnblogs.com/intsmaze/p/5243326.html
Copyright © 2011-2022 走看看