SpringMVC 数据绑定

这是我在 慕课网 观看 SpringMVC 数据绑定入门 所做的学习笔记
其中包含对 **List,Set,Map,JSON,XML 的数据绑定以及 PropertyEditor、Formatter、Converter 三种自定义类型转换器 **

  • List 类型绑定

    • 特点

      • List 对象绑定需要建立一个 List 集合包装类
      public class User {
          private int age;
          private String name;
          // 省略 setter getter
      }
      public class ListUserWrap {
          private List userList;
          // 省略 setter getter
      }
      
      • List 的长度为前台传入的 ** 集合最大下标加 1**
      @ResponseBody
      @RequestMapping(value = "/list2")
      public String list2(ListUserWrap listUserWrap) {
          return "listUserWrapSize:" + listUserWrap.getUserList().size() + "\tlistUserWrap:" + listUserWrap;
      }
      
    • 测试数据

      http://localhost/list2?userList[0].name=a&userList[1].name=b
      listUserWrapSize:2 listUserWrap:ListUserWrap(userList=[User(age=0, name=a), User(age=0, name=b)])
      http://localhost/list2?userList[0].name=a&userList[1].name=b&userList[3].name=c
      listUserWrapSize:4 listUserWrap:ListUserWrap(userList=[User(age=0, name=a), User(age=0, name=b), User(age=0, name=null), User(age=0, name=c)])

  • Set 类型绑定

    • 特点

      • Set 对象绑定需要建立一个 Set 集合包装类
      • 需要先定义 Set 集合长度, 并且前台传过来的 Set 长度不能越界, 否者报错
      • ** 设置 Set 长度时需要注意重写对象的 hashCode,equals 方法, 否者后面的会掩盖前面的 **
      public class SetUserWrap {
          private Set userSet;
          // 省略 setter getter
          public SetUserWrap() {
              userSet = new LinkedHashSet<>();
              userSet.add(new User());
              User user = new User();
              user.setName("b");
              userSet.add(user);
          }
      }
      
    • 测试数据

      http://localhost/set?userSet[0].name=a 因为预先定义的第二个对象的 name 为 b, 所以此处返回 b
      setUserWrapSize:2 setUserWrap:SetUserWrap(userSet=[User(age=0, name=a), User(age=0, name=b)])
      http://localhost/set?userSet[0].name=a&userSet[1].name=bbb
      setUserWrapSize:2 setUserWrap:SetUserWrap(userSet=[User(age=0, name=a), User(age=0, name=bbb)])

  • Map 类型绑定

    • 特点

      • 建立一个 Map 包装类
      public class MapUserWrap {
          private Map userMap;
          // 省略 setter getter
      }
      @ResponseBody
      @RequestMapping(value = "/map")
      public String map(MapUserWrap mapUserWrap) {
          return "mapUserWrapSize:" + mapUserWrap.getUserMap().size() + "\tmapUserWrap:" + mapUserWrap;
      }
      
    • 测试数据

      http://localhost/map?userMap["a"].name=a&userMap["b"].name=b
      mapUserWrapSize:2 mapUserWrap:MapUserWrap(userMap={a=User(age=0, name=a), b=User(age=0, name=b)})
      http://localhost/map?userMap["a"].name=a&userMap["a"].name=b
      mapUserWrapSize:1 mapUserWrap:MapUserWrap(userMap={a=User(age=0, name=a,b)})

  • JSON 类型绑定

    • 前台在 body 区域传入以下类型格式字符串
    {
        "name":"a",
        "age":1
    }
    
    @ResponseBody
    @RequestMapping(value = "/json")
    public String json(@RequestBody User user) {
        return user.toString();
    }
    
  • XML 类型绑定

    • 前台在 body 区域传入以下类型格式字符串
    
        a
        1
    
    
    • 建立一个 XML 包装类
    @XmlRootElement(name = "xmluser")// 根节点标签名
    public class XmlUser {
        @XmlElement(name = "name")// 属性标签名
        private String name;
        @XmlElement(name = "age")// 属性标签名
        private int age;
    }
    
    @ResponseBody
    @RequestMapping(value = "/xml")
    public String xml(@RequestBody XmlUser xmlUser) {
        return xmlUser.toString();
    }
    
  • 自定义类型转换 - PropertyEditor

    在 Controller 中编写一个带有 InitBinder 注解的方法, 传入 WebDataBinder 对象, 使用该对象注册指定类型的转换关系, 对该方法所在 Controller 中使用该类型的方法参数有效

    @ResponseBody
    @RequestMapping(value = "/date")
    public String date(Date date) {
        return date.toLocaleString();
    }
    @ResponseBody
    @RequestMapping(value = "/date2")
    public String date2(Date date2) {
        return date2.toLocaleString();
    }
    
    @InitBinder("date")// 指定对变量名为 date 进行转换, 不会对 date2 生效
    private void initDate(WebDataBinder binder) {
        binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
        //binder.registerCustomEditor(Class requiredType, PropertyEditor propertyEditor)
        //new CustomDateEditor(DateFormat dateFormat, boolean allowEmpty)
        //allowEmpty 是否允许 Date 对象为空
    }
    
  • 自定义类型转换 - Formatter

    根据 String 类型自定义转换规则转换成需要的类型, 需要实现 org.springframework.format.Formatter 接口,T 为想要转换的结果类型

    • 创建自定义 Formatter
    public class DateFormatter implements Formatter {
        @Override
        public Date parse(String text, Locale locale) {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            Date date = null;
            try {
                date = dateFormat.parse(text);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return date;
        }
    
        @Override
        public String print(Date object, Locale locale) {
            return null;
        }
    }
    
    • 将自定义的 Formatter 注入到 SpringMVC 默认的 FormattingConversionServiceFactoryBean 中, 同时将默认转换规则服务类配置为已经被注入的 bean 对象
    
    
        ,
            
                
            
        
    
    
  • 自定义类型转换 - Converter

    自己指定数据来源类型及转换结果类型, 相比 Formatter 更为灵活, 需要实现 org.springframework.core.convert.converter.Converter 接口,S 为来源类型,T 为结果类型

    • 创建自定义 Converter
    public class DateConverter implements Converter {
        @Override
        public Date convert(String source) {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            Date date = null;
            try {
                date = dateFormat.parse(source);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return date;
        }
    }
    
    • 将自定义的 Converter 注入到 SpringMVC 默认的 FormattingConversionServiceFactoryBean 中, 同时将默认转换规则服务类配置为已经被注入的 bean 对象
    
    
        
            
                
            
        
    
    

你可能感兴趣的:(SpringMVC 数据绑定)