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<User> 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<User> 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<String, User> 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 区域传入以下类型格式字符串
    <xmluser>
        <name>a</name>
        <age>1</age>
    </xmluser>
    
    • 建立一个 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> 接口,T 为想要转换的结果类型

    • 创建自定义 Formatter
    public class DateFormatter implements Formatter<Date> {
        @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 对象
    <mvc:annotation-driven conversion-service="myFormattingConversionService"/>
    <bean id="myFormattingConversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="formatters">,<!-- 此处为 formatters-->
            <set>
                <bean class="{包路径}.DateFormatter"></bean>
            </set>
        </property>
    </bean>
    
  • 自定义类型转换 - Converter

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

    • 创建自定义 Converter
    public class DateConverter implements Converter<String, Date> {
        @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 对象
    <mvc:annotation-driven conversion-service="myFormattingConversionService"/>
    <bean id="myFormattingConversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="converters"><!-- 此处为 converters-->
            <set>
                <bean class="{包路径}.DateConverter"></bean>
            </set>
        </property>
    </bean>
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 基本类型 请求: /baseType?age=2结果: age:20 数组 请求: /array?name=tom...
    缓慢移动的蜗牛阅读 369评论 0 2
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,886评论 18 139
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,759评论 18 399
  • 打破惯性防卫-绿灯思维 什么是习惯性防卫 这是一种非常常见的心理学现象。当我们感到自己的观点、尊严可能会受到挑...
    金勇Maya阅读 456评论 0 2
  • 在东方天际泛起鱼肚白之前 一片瑰丽的红霞悄悄地 夹在五六点钟的晨光缝隙间 短暂、多变、不可描摹
    鹅笼书生_阅读 242评论 0 0