每周分享之《JSR303 Bean Validation介绍以及在项目中的使用》
项目中参数校验,用到JSR 303,在此总结梳理下知识脉络,抛砖引玉。
一、基础1.What is JSR?
JSR是Java Specification Requests的缩写,意思是Java 规范提案。任何人都可以提交JSR,以向Java平台增添新的API和服务。JSR已成为Java界的一个重要标准。
2.Why use JSR 303?
问题:在通常的情况下,应用程序是分层的,不同的层由不同的开发人员来完成。很多时候同样的数据验证逻辑会出现在不同的层,这样耗时且容易出错,导致代码冗余和一些管理的问题。
想法:为了避免这样的情况发生,最好是将验证逻辑与相应的域模型进行绑定。(开发者更倾向于将验证规则直接放到 Java Bean 本身,使用注解的方式进行验证规则的设计。)
解决方案:Bean Validation为JavaBean 验证定义了相应的元数据模型(注解)和 API,它是一个运行时的数据验证框架,来使用其定义的验证检查JavaBean属性值,在验证之后验证的错误信息会被马上返回(Hibernate Validator 是 Bean Validation 的参考实现 ,提供了 JSR 303 规范中所有内置 constraint 的实现,除此之外还有一些附加的 constraint)。
3.常用
·空检查
@NotNull 验证对象 是否不为null, 无法查检长度为0的字符串
@NotEmpty 检查约束元素(String类、Collection、Map、数组)是否为NULL或者是EMPTY(实际意义等同于 @NotNull 和 @Size(min=1)的组合)
@NotBlank 检查约束字符串 是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格
·长度检查
@Length(max, min) Validates that the annotated 字符串 is between min and max included.
@Size(max, min) 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内
·数字大小
@Min(value) 验证 Number 和 String 对象是否大等于指定的值
@Max(value) 验证 Number 和 String 对象是否小等于指定的值
@Range(min, max) 检查数字是否介于min和max之间
@DecimalMin 验证 Number 和 String 对象是否大等于指定的值,这个约束的参数是一个通过BigDecimal定义的最小值的字符串表示,小数存在精度
@DecimalMax 验证 Number 和 String 对象是否小等于指定的值,这个约束的参数是一个通过BigDecimal定义的最大值的字符串表示,小数存在精度
注:上述注解具体对象为 BigDecimal,BigInteger, byte,short, int, long等任何Number或CharSequence(存储的是数字)子类型。
·小数精度
@Digits (integer, fraction) 验证 Number 和 String 的构成是否合法(符合指定格式的数字),integer是整数精度(整数位数上限),fraction是小数精度(小数位数上限)
4.constraint (约束)
通常由 annotation 和相应的 constraint validator 组成,它们是一对多的关系。在运行时,Bean Validation 框架本身会根据被注释元素的类型来选择合适的 constraint validator 对数据进行验证。(自己也可使用内置的constraint定制化所需constraint,或者新开发constraint — 继承ConstraintValidator)
二、高级1.嵌套(递归)校验
场景:被校验JavaBean 包含的属性,有的是引用类型且包含需要校验的参数
使用方式:该属性前面声明@Valid,才会对属性对象内的注解进行验证,否则将不予验证;如果关联对象是个集合或者数组,那么对其中的元素进行递归校验,如果是一个map,则对其中的值部分进行校验。
2.组
场景:对接不同项目,有些参数有时是需要的,有时又是不需要的;再比如说对于一个实体类来的id来说,保存的时候是不需要的,对于更新时是必须的
使用方式:@Validated( { First.class, Second.class }) ,@Valid(groups=GroupA.class),@NotEmpty(message = "lastname may be empty",groups = GroupA.class)
作用:无需对该对象中所有的约束进行验证,只需要对该组定义的一个子集进行验证即可
3.自定义constraint (约束)
4.非参数校验的位置
其实在整个程序的任何地方都可以调用 JSR 303 API 去对数据进行校验,然后将校验后的结果返回:
流程:
结束语
把项目中的问题作为切入点,这次整理让我自己受益良多:更加清楚地梳理&充实了知识框架,也了解到了更多工作时不一定用到的知识(可以作为本人待探索的领域)。 接下来,要解决自己一直以来的软肋,要动手创建项目 to 实践整理出的理论。
参考文章
1.JSR 303 - Bean Validation 介绍及最佳实践 https://www.ibm.com/developerworks/cn/java/j-lo-jsr303/
2.百度百科
3.Java的Validator框架概述 http://blog.csdn.net/zhu_tianwei/article/details/43272181
4.http://blog.csdn.net/wangpeng047/article/details/41726299
5.https://www.cnblogs.com/yangzhilong/p/3724967.html
6.http://jinnianshilongnian.iteye.com/blog/1733708