目录
1.在BeanWrapper中使用PropertyEditor
2.在BeanWrapper中使用ConversionService
二、数据绑定器:DataBinder与WebDataBinder
三、HTTP消息转换器(HttpMessageConverter)
1.HttpEntity、RequestEntity和ResponseEntity
2.1 方式一:HttpServletResponse手动指定
Bean Wrapper(Bean封装器)和DataBinder(数据绑定器)是Spring中的两种数据绑定的实现。两者都实现了PropertyEditorRegister和TypeConverter接口,可以实现数据的类型转换。DataBinder还可以用来效验数据有效性,在SpringMVC容器中,使用WebDataBinder将前端请求参数转换为后端类型的对象,如果要处理JSON等类型的请求和响应,则需要结合HTTP消息转换器及@RequestBody和@ResponseBody注解。
一、Bean封装器:BeanWrapper
BeanWrapper是Spring提供的对Bean包装的接口,BeanWrapperImpl是对该接口的实现。Bean通过BeanWrapperImpl封装后,可以通过调用getPropertyValue()和setPropertyValue()方法,以统一的方式对属性进行操作。以User类(存在一个String类型的userName属性)为例,使用BeanWrapperImpl对User类对象封装后,操作userName属性的方式如下:
public static void main(String[] args) {
User user = new User();
BeanWrapperImpl userWrapper = new BeanWrapperImpl(user);
userWrapper.setPropertyValue("userName", "User 1");
String userName = (String) userWrapper.getPropertyValue("userName");
}
使用BeanWrapperImpl对Bean进行封装的好处是可以让不同类型Bean的不同属性使用统一的方式获取和设置值,除此之外,Bean还能结合属性编辑器(PropertyEditor)和类型转换器(ConversionService)对Bean中的属性进行类型转换。
1.在BeanWrapper中使用PropertyEditor
Spring核心容器内部默认就是使用BeanWrapper结合属性编辑器初始化Bean。除了默认的属性编辑器,自定义的属性编辑器通过registerCustomEditor()方法注册到BeanWrapper对象中,该方法的第一个参数是需要转换的目标类型,第二个参数是编辑器的对象。
以User类(存在一个Date类型的userBirthday属性)为例,BeanWrapper默认支持yyyy/mm/dd日期格式的转换,如下结合CustomDateEditor实现对yyyy-mm-dd日期字符串转换的示例:
public static void main(String[] args) {
User user = new User();
BeanWrapperImpl userWrapper = new BeanWrapperImpl(user);
userWrapper.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-mm-dd"), false));
userWrapper.setPropertyValue("userName", "User 1");
userWrapper.setPropertyValue("userBirthday", "2021-04-30"); // 设置字符串类型的日期,会被属性编辑器转换为Date类型然后赋值
System.out.println(userWrapper.getPropertyValue("userBirthday") instanceof Date); // true
}
2.在BeanWrapper中使用ConversionService
BeanWrapper通过setConversionService()设置转换器服务,如果需要,可以在转换器服务中添加自定义的转换器。Spring还支持在日期和数字类型的属性中使用注解进行类型转换的细粒度控制,对应注解@DateTimeFormat和@NumberFormat。比如设置上面的userBirthday转换格式为yyyy+mm+dd,则只需要在属性中添加如下注解:
public class User {
@DateTimeFormat(pattern = "yyyy+mm+dd")
private Date userBirthday;
//……
}
public static void main(String[] args) {
User user = new User();
BeanWrapperImpl userWrapper = new BeanWrapperImpl(user);
DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService();
userWrapper.setConversionService(conversionService); // 设置转换器服务
userWrapper.setPropertyValue("userBirthday", "2021+04+30");
System.out.println(userWrapper.getPropertyValue("userBirthday") instanceof Date); // true
}
二、数据绑定器:DataBinder与WebDataBinder
与BeanWrapper类似,DataBinder可以对Bean进行封装绑定。DataBinder实现了PropertyEditorRegister,可以注册自定义的属性编辑器:DataBinder包含一个ConversionService属性,在绑定器初始化时容器会注入该转换器服务的依赖,也可以添加自定义的转换器和格式化转换器。除此之外,DataBinder还提供了数据有效性验证等功能,DataBinder有一个子类WebDataBinder,用于SpringMVC中的数据绑定。
1.数据绑定器(DataBinder)
以User类(存在一个Date类型的userBirthday属性)为例如下:
public static void main(String[] args) {
User user = new User();
// 绑定对象: 第一个参数是(需要绑定的对象),第二个参数是(绑定的对象的名字)
DataBinder dataBinder = new DataBinder(user, user.getClass().getName());
// 添加格式转换器
dataBinder.addCustomFormatter(new DateFormatter("yyyy-mm-dd"));
// 属性值对象初始化
MutablePropertyValues propertyValues = new MutablePropertyValues();
propertyValues.add("userName", "Zhang San"); // 添加userName属性值
propertyValues.add("userBirthday", "2021-04-30");// 添加userBirthday属性值
dataBinder.bind(propertyValues); // 绑定属性值
// 得到绑定后的结果
BindingResult bindingResult = dataBinder.getBindingResult();
// 从绑定结果中得到