1.数据绑定工厂的使用
数据绑定工厂能够创建数据绑定器,将数据绑定到对象中,比如说当接收到请求时,经过http协议解析后数据刚开始都是字符串,此时我们希望将这些属性进行类型转换,并为对象赋值,示例如下:
1)先创建两个实体类Student和Teacher
@Getter
@Setter
@ToString
public class Student {private String name;private int age;private Date birthday;private Teacher teacher;
}@Getter
@Setter
@ToString
public class Teacher {private String name;
}
2)使用ServletRequestDataBinderFactory工厂创建数据绑定器,进行数据绑定
public class Test01 {public static void main(String[] args) throws Exception {// 模拟一个Web请求MockHttpServletRequest request = new MockHttpServletRequest();// 简单字符串属性request.setParameter("name", "lm");// 需要将字符串转换为整型request.setParameter("age", "28");// 需要能够解析自定义格式request.setParameter("birthday", "1999-01-02");// 需要能够绑定到对象中的属性request.setParameter("teacher.name", "lhm");Student student = new Student();// 使用数据绑定工厂创建数据绑定器,此时没有传入bindMethod或initializerServletRequestDataBinderFactory factory = new ServletRequestDataBinderFactory(null, null);WebDataBinder dataBinder = factory.createBinder(new ServletWebRequest(request), student, "student");dataBinder.bind(new ServletRequestParameterPropertyValues(request));System.out.println(student);}
}
执行Test01测试,绑定失败,会报如下错误:
这是因为我们的数据绑定工厂中没有传入bindMethod或者initializer,无法自定义解析日期格式,创建Date对象时没有使用默认的格式导致解析错误,此时我们有如下2种方式完成自定义数据格式的绑定
1.1 向数据绑定工厂中传入bindMethod
通过@InitBinder注解向数据绑定工厂中添加bindMethod
1)首先创建自定义的转换器类
public class DateFormatter implements Formatter<Date> {private final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-mm-dd");@Overridepublic Date parse(String text, Locale locale) throws ParseException {return simpleDateFormat.parse(text);}@Overridepublic String print(Date date, Locale locale) {return simpleDateFormat.format(date);}
}
2)创建一个类并添加@InitBinder修饰的转换方法
public class MyBinder {@InitBinderpublic void bind(WebDataBinder webDataBinder) {// 添加自定义的转换器webDataBinder.addCustomFormatter(new DateFormatter());}
}
3)修改测试代码,在数据转换工厂中添加bindMethod,即可绑定成功
public class Test02 {public static void main(String[] args) throws Exception {// 模拟一个Web请求MockHttpServletRequest request = new MockHttpServletRequest();// 简单字符串属性request.setParameter("name", "lm");// 需要将字符串转换为整型request.setParameter("age", "28");// 需要能够解析自定义格式request.setParameter("birthday", "1999-01-02");// 需要能够绑定到对象中的属性request.setParameter("teacher.name", "lhm");Student student = new Student();// 添加bindMethodInvocableHandlerMethod method = new InvocableHandlerMethod(new MyBinder(), MyBinder.class.getMethod("bind", WebDataBinder.class));// 使用数据绑定工厂创建数据绑定器,此时没有传入bindMethod或initializerServletRequestDataBinderFactory factory = new ServletRequestDataBinderFactory(Arrays.asList(method), null);WebDataBinder dataBinder = factory.createBinder(new ServletWebRequest(request), student, "student");dataBinder.bind(new ServletRequestParameterPropertyValues(request));// 打印Student(name=lm, age=28, birthday=Sat Jan 02 00:01:00 CST 1999, teacher=Teacher(name=lhm))System.out.println(student);}
}
1.2 向数据绑定工厂中传入initializer
修改测试代码,在数据转换工厂中添加initializer,使用ConversionService接口进行转换,即可绑定成功
public class Test03 {public static void main(String[] args) throws Exception {// 模拟一