spring mvc(数据绑定) DataBinding 过程源码分析

2月 4, 2018 |

目录
1、PropertyEditor接口和ConversionService服务
2、ConversionService接口的注入过程
3、Formatter接口
4、@ModelAttribute 注解
5、DataBinding失败处理
6、验证
本文由javacoder.cn整理,转载注明处理

无论是spring mvc的数据绑定(将各式参数绑定到@RequestMapping注解的请求处理方法的参数上),还是BeanFactory(处理@Autowired注解)都会使用到BeanWrapper 接口,本文主要讲解BeanWrapper 在spring mvc的数据绑定阶段的应用
执行数据绑定的序列图如下

PropertyEditor接口和ConversionService服务

数据绑定主要分两步,从HttpServletRequest取原始的数据,用户输入的内容大多是字符串表示的值,比如日期表示为'yyyy-MM-dd'格式的字符串;第二步就是将字符串形式的值转换为对应的类型,比如将'yyyy-MM-dd'转换为Date类型。这时就需要借助于spring 的类型转换系统了(TypeConversion)
主要的决断逻辑在
TypeConverterDelegate.convertIfNecessary() 方法中,主要的逻辑如下

主要的逻辑归纳如下:
如果没有自定义的PropertyEditor,那么使用ConversionService服务来转换
如果ConversionService 不支持该类型的数据转换,且有自定义的PropertyEditor,或者有默认的PropertyEditor, 那么使用PropertyEditor进行转换
如果数据类型不匹配,比如是一个数组,map, List等对象,那么相应的特殊处理

ConversionService接口的注入过程

当spring 上下文启动时, 解析如下元素
<mvc:annotation-driven/>
如果annotation-driven 元素没有conversion-service属性,那么直接添加一个表示FormattingConversionServiceFactoryBean的BeanDefinitio到DefaultListableBeanFactory中
在FormattingConversionServiceFactoryBean.afterPropertiesSet() 中将查找到的converter和formatter注册到conversionService中。

Formatter接口

为了更好的适应数据在字符串与各种类型中转换, spring mvc定义了新的Formatter接口
public interface Formatter extends Printer, Parser {}
然后分别定义了ParserConverter(Parser.parse())和PrinterConverter(Printer.print())将新的接口集成到ConversionService中,见序列图中ParserConverter的调用链

@ModelAttribute 注解

DataBinding失败处理

Controller中常有如下样例代码

在每个binding参数后,一般会跟一个BindingResult对象,该对象表示DataBinding是否成功, 注意,当绑定失败时和initAddUser请求处理器返回相同的逻辑view。

验证

介绍@Valid的文章很多,这里提示一下嵌套属性的验证

UserListWrapper的userList属性的类型为List<UserVo> , 为了让UserVo中的校验规则(constraints)被验证, 需要在userList属性上添加@Valid注解,如果使用的jdk为jdk8及以上, 可以按如下格式改写
private List<@Valid UserVo> userList = new ArrayList();

Posted in: spring practise

Comments are closed.