SpringMVC数据绑定

springmvc帮我们实现了 : 基本数据类型,包装类型,自定义类型,数组,map,list,set ,json,xml , 和多层级类型的数据绑定 ,我们来看看它是怎么做到的 ……

基本类型

  • 如果前端不传入,可导致NPE . 可使用包装类解决

数组

  • 同name的会自动封装到array

    // localhost:8080/array?name=wesley&name=abner&name=test
    @ResponseBody
    @RequestMapping("array")
    public controllerMethod(String [] names){
        return Arrays.toString(names);
    }
    

同属性对象

// 用户对象
class User{
    private String name;
    private int age;
    private Area area; // 地区信息
    
    //get set ……
}
// 员工对象
class Emp{
    private String name;
    private int age;
   	Date hiredate; // 入职日期
    //get set ……
}


// --------------------------------- 
@ResponseBody
@RequestMapping("multiField")
public controllerMethod(User user,Emp emp){
    return user.toString() + " " + emp.toString();
}


// localhost:8080/user?name=wesley&age=27
// 如果不处理,user 和emp 对象都会被注入值  
@InitBinder("user")
public void initUser(WebDataBinder binder){
    binder.setFieldDefaultPrefix("user");
}
@InitBinder("emp")
public void initUser(WebDataBinder binder){
    binder.setFieldDefaultPrefix("emp");
}
// localhost:8080/user?user.name=wesley&user.age=27&emp.name=abner&emp.age=20

// OK...


多层级对象

class User{
    private String name;
    private int age;
    private Area area; // 地区信息
    
    //get set ……
}
// 地区类
class Area {
    private String province;
    private String city;
    private String area;
    // get set ……
}


// --------------------------------- 
@ResponseBody
@RequestMapping("user")
public controllerMethod(User user){
    return user.toString();
}

// localhost:8080/user?name=wesley&age=27&area.city=hy&area.province=hunan

List,Set,Map

Tips : 使用自定义类把 list,set,map 包起来

  • list
class UserListVO{
    private List<User> users;   
    //get set ……
}
@ResponseBody
@RequestMapping("userList")
public controllerMethod(UserListVO users){
    return users.toString();
}
// localhost:8080/userList?users[0].name=wesley&users[0].age=27&users[1].name=name2&users[1].age=23
  • set

    • springmvc对set的注入很奇葩,一般不建议使用
  • map

    public class UserMapVO {
        private Map<String,User> users;
        public Map<String, User> getUsers() {
            return users;
        }
        public void setUsers(Map<String, User> users) {
            this.users = users;
        }
        @Override
        public String toString() {
            return "UserMapVO [users=" + users + "]";
        }
    }
    
    @ResponseBody
    @RequestMapping("map")
    public controllerMethod(UserMapVO users){
        return users.toString();
    }
    // localhost:8080/map?users["A"]。name=wesley&users["A"].age=27&users["B"].name=name2&users["B"].age=23
    

json,xml绑定

  • json相关包

    <dependency>
         <groupId>com.fasterxml.jackson.core</groupId>
         <artifactId>jackson-databind</artifactId>
    </dependency>
    
  • controller

    @ResponseBody
    @RequestMapping("json")
    public controllerMethod(@RequestBody User user){
        return user.toString();
    }
    // localhost:8080/json
    // body usejson
    // Content-Type: application/json
    {
      "name": "wesley",
      "age": 27
    }
    
    
  • xml

    • 引入 spring-oxm jar

    • 添加element注解

      @XmlRootElement(name="user")
      class User{
          private String name;
          private int age;
          private Area area; // 地区信息
          
          //get set ……
          @XmlElement
          public String getName(){
              return name;
          }
      }
      
      // Content-Type: application/xml
      /*
      <?xml version="1.0" encoding = "utf-8"?>
      <user>
      	<name>wesley</name>
      	<age>28</age>
      </user>
      */
      

类型转换器

  • PropertyEditorSupport

    SpringMVC 自定义全局PropertyEditor

  • Converter

    springmvc帮我们定义了很多常用的转换器,一般拿来用就OK,当然我们也可以自定义Formatter,Converter然后交给springmvc

    // 这里的S表示源类型,T表示目标类型。
    public interface Converter<S, T> {
        T convert(S var1);
    }
    // 将String类型转换成Date类型的Converter
    public class StringToDateConverter implements Converter<String, Date>{
        private static final Log logger = LogFactory.getLog(StringToDateConverter.class);
        private String datePattern;
    
        public StringToDateConverter(String datePattern) {
            this.datePattern = datePattern;
        }
    
        public Date convert(String s) {
            try {
                SimpleDateFormat dateFormat = new SimpleDateFormat(datePattern);
                dateFormat.setLenient(false);
                return dateFormat.parse(s);
            } catch (ParseException e) {
                throw new IllegalArgumentException("invalid date format. Please use this pattern\"" + datePattern + "\"");
            }
        }
    }
    
    <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="app06a.converter.StringToDateConverter">
                    <constructor-arg name="datePattern" value="yyyy-MM-dd"/>
                </bean>
            </set>
        </property>
    </bean>
    
    <mvc:annotation-driven conversion-service="conversionService"/>
    
  • Formatter

    public class DateFormatter implements Formatter<Date>{
        private String datePattern;
        private SimpleDateFormat dateFormat;
    
        public DateFormatter(String datePattern) {
            this.dateFormat = dateFormat;
            dateFormat = new SimpleDateFormat(datePattern);
            dateFormat.setLenient(false);
        }
        public Date parse(String s, Locale locale) throws ParseException {
            try {
                SimpleDateFormat dateFormat = new SimpleDateFormat(datePattern);
                dateFormat.setLenient(false);
                return dateFormat.parse(s);
            } catch (ParseException e) {
                throw new IllegalArgumentException("invalid date format. Please use this pattern\"" + datePattern + "\"");
            }
        }
    
        public String print(Date date, Locale locale) {
            return dateFormat.format(date);
        }
    }
    
    <!-- formatters -->
    <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="formatters">
            <set>
                <bean class="app06a.formatter.DateFormatter">
                    <constructor-arg name="datePattern" value="yyyy-MM-dd"/>
                </bean>
            </set>
        </property>
    </bean>
    
    <mvc:annotation-driven conversion-service="conversionService"/>
    
    
  • Converter是一般工具,可以将一种类型转换成另一种类型。例如,将String转换成Date,或者将Long转换成Date。Converter既可以用在web层,也可以用在其它层中。 Formatter只能将String转成成另一种java类型。例如,将String转换成Date,但它不能将Long转换成Date。所以,Formatter适用于web层。为此,在Spring MVC应用程序中,选择Formatter比选择Converter更合适。

  • spring-mvc的Conveter和Formatter

posted @ 2021-06-27 17:42  沉梦匠心  阅读(118)  评论(0)    收藏  举报