数据绑定
数据绑定流程
- springmvc框架将ServletRequest对象及目标方法的入参实例传递给WebDataBinderFactory实例,以创建DataBinder实例对象
- DataBinder调用装配在springmvc上下文中的ConversionService组件进行数据类型转换、数据格式化工作。将Servlet中的请求信息填充到入参对象中
- 调用Vaildator组件对已经绑定了请求消息的入参对象进行数据合法性检验,并最终生成数据绑定结果BindingData对象
- springmvc抽取BindingResult中的入参对象和校验错误对象,将他们赋给处理方法的响应入参
ConversionService
org.springframework.core.convert.ConversionService是springmvc中进行数据类型转换的接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public interface ConversionService {
boolean canConvert(Class<?> sourceType, Class<?> targetType);
boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType);
<T> T convert(Object source, Class<T> targetType);
Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType);
}
|
可以利用ConversionServiceFactoryBean来定义一个ConversionService,其中包含了很多内置的类型转换器
1 2 3 4 5 6 7 8 9 10
| public void afterPropertiesSet() { this.conversionService = createConversionService(); ConversionServiceFactory.registerConverters(this.converters, this.conversionService); }
protected GenericConversionService createConversionService() { return new DefaultConversionService(); }
|
自定义类型转换器
可通过ConversionServiceFactoryBean的converters属性注册自定义的类型转换器
可以使用三种方式实现自定义类型转换器
实现Converter接口
1 2 3 4
| public interface Converter<S, T> { T convert(S var1); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| @Component public class UserConverter implements Converter<String, User> { @Override public User convert(String s) { if(s != null && !"".equals(s)){ String[] values = s.split(":"); if(values != null && values.length > 0){ User user = new User(); if("null".equals(values[0])){ user.setId(0); } else { user.setId(Integer.parseInt(values[0])); }
if("null".equals(values[1])){ user.setName(""); } else { user.setName(values[1]); } return user; } } return null; } }
|
配置
1 2 3 4 5 6 7 8 9 10
| <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <list> <ref bean="userConverter"/> </list> </property> </bean>
<mvc:annotation-driven conversion-service="conversionService"/>
|
1 2 3 4 5
| @RequestMapping("/testConverter") public String testConverter(User user){ System.out.println(user); return "hello"; }
|
ConverterFactory
ConverterFactory的作用是将相同系列的多个Converter封装在一起
1 2 3 4 5 6
| public interface ConverterFactory<S, R> {
<T extends R> Converter<S, T> getConverter(Class<T> targetType);
}
|
GenericConverter
GenericConverter会根据源类对象及目标类对象的上下文进行类型转换
1 2 3 4 5 6 7 8 9
| public interface GenericConverter {
Set<ConvertiblePair> getConvertibleTypes();
Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType);
}
|