数据的校验是做web开发不可或缺的部分,前端的js校验可以涵盖大部分的校验职责,如用户名唯一性,生日格式,邮箱格式校验等等常用的校验。但是为了避免用户绕过浏览器,使用http工具直接向后端请求一些违法数据,服务端的数据校验也是必要的。这样避免了脏数据落到数据库中也避免了一些无效的操作。
1.JSR303/JSR-349,hibernate validation,spring validation之间的关系:
JSR303是一项标准,JSR-349是其的升级版本,添加了一些新特性,他们规定一些校验规范即校验注解,如@Null,@NotNull,@Pattern,他们位于javax.validation.constraints包下,只提供规范不提供实现。而hibernate validation是对这个规范的实践(不要将hibernate和数据库orm框架联系在一起),他提供了相应的实现,并增加了一些其他校验注解,如@Email,@Length,@Range等等,他们位于org.hibernate.validator.constraints包下。
2.校验的方式,目前我们的project中,大部分是在后端自己写逻辑进行校验,比如判断日期格式是否是yyyy-mm-dd,或者判断传入参数是否是限定的几个中的一个,这导致写了很多无聊的逻辑....其实spring提供了校验的类库, 我们可以在其基础上构建自己需要的功能。
构建校验的顺序:
值得注意的地方:
<1> 参数Foo前需要加上@Validated注解,表明需要spring对其进行校验,而校验的信息会存放到其后的BindingResult中。注意,必须相邻,如果有多个参数需要校验,形式可以如下。foo(@Validated Foo foo, BindingResult fooBindingResult ,@Validated Bar bar, BindingResult barBindingResult);即一个校验类对应一个校验结果。
<2> 校验结果会被自动填充,在controller中可以根据业务逻辑来决定具体的操作,如跳转到错误页面。
下面着重介绍下自定义校验,比如最近的一个需求,前端传入String 类型的参数duration,周期只能是4w,12w,26w,52w,104w这五个中的一个,如果不是,返回invalidArgumention,这种恶心又必要的功能,还是交给自定义校验好了。。。。。。
自定义校验顺序:
1.创建自定义注解
validatedBy 中填写自己传教的校验类
2.编写自己的校验类
校验类要继承ConstraintValidator,然后isValid函数里面验证参数是否有效。
3.在Controller方法中传入校验类类型的参数
原理及其调用链:
在分发url请求调用doDispatch之后,resolveArgument
然后调用SpringValidatorAdapter下的方法