Hibernate Validator常用约束(包含JSR规范)
在程序开发的时候,对入参进行参数校验是一个非常常见的操作,检验的方法无非手动校验和自动校验,如果你是在网关(web应用)等进行校验的话,springmvc和springboot都提供了便捷的检验方法,但是如果你是在普通java应用间进行接口调用的时候,这个时候由于是非web,那么自动参数校验可能要自己想办法去实现了。
我这里已经实现了一个校验插件,即插即用,欢迎批评指正:github - EasyValidate
内部java应用(spring或者springboot),相互间通过rpc相互调用
通过rpc的拦截器实现,优点:链路最短,请求通过端口接口,第一时间得到检验,缺点:这个拦截器依赖于rpc的类型,当前项目使用的是grpc的二次封装,且是由别人维护,拦截器的有效性可能不是自己无法保证,可能哪一天rpc的项目框架变动,拦截器就不生效了
spring aop,这个就交给了spring容器去做了,在spring容器调用相关接口方法的时候,拦截对应的方法,根据入参的有效性进行方法执行的干预,优点:只依赖于容器,缺点:调用的service必须是spring管理的bean
这里选择了方案二,只需要开发响应的切面(aspect)即可,对于参数校验的具体实现,不需要自己从头开发,,对于spring应用,需要手动开启全局aop代理,如下配置,springboot则自动开启
<aop:aspectj-autoproxy />
对于校验方法的选择有一下几种:
自定义参数校验框架,编写自定义校验注解,通过aop拦截指定注解或者方法,逐个遍历方法filed变量,并检查是否有对应的自定义校验注解,如果有则检查字段的有效性,此方法缺点比较明显,因为要定义一大批
验证注解,如@number @min等,属于重复造轮子,其实这部分java规范JSR-303规范已经定义
Spring方法级别数据校验:@Validated + MethodValidationPostProcessor,此方案是spring原生自带,简洁优雅,只可检验方法,不可校验bean,此方案可配合全局异常处理联合使用
具体参考:Spring方法级别数据校验
hibernater-validator依赖于validation-api,说明这个框架是实现了bean validation规范的,从测试中也可以看出,既可以使用javax.validation包下的注解来做校验,也可以使用自身的注解;
而oval不依赖于validation-api.两者大同小异,实现的原理也差不多. Java开源验证框架Oval是一个可扩展的Java对象数据验证框架,功能强大使用简单,验证规则可通过配置文件、注解等方式进行设置,
规则的编写可以使用纯Java、JavaScript 、Groovy 、BeanShell等语言。
使用需要引入:
<dependency>
<groupId>net.sf.oval</groupId>
<artifactId>oval</artifactId>
<version>1.81</version>
</dependency>
Hibernate validator,遵循JSR-380规范,和上面的spring提供的方法级别校验大同小异,除了方法的校验,可提供bean的校验,比较灵活,需要引入额外的jar
JSR250与资源控制提出之后相续提交了JSR-303、JSR-349以及JSR-380来完善使用注解进行数据校验的机制,这三个JSR也被称为Bean Validation 1.0、Bean Validation 1.1和Bean Validation 2.0,统称为Bean Validation
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.18.Final</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
<version>3.0.1-b09</version>
</dependency>
这里最终选择了hibernater-validator,方便拿到返回值,返回原生的返回值,并且既可以校验method,也可以检验pojo
官方文档: Hibernate Validator 官方文档和API
快速入门: Hibernate Validator 快速入门
空与非空检查
注解 | 支持Java类型 | 说明 |
---|---|---|
@Null | Object | 为null |
@NotNull | Object | 不为null |
@NotBlank | CharSequence | 不为null,且必须有一个非空格字符 |
@NotEmpty | CharSequence、Collection、Map、Array | 不为null,且不为空(length/size>0) |
Boolean值检查
注解 | 支持Java类型 | 说明 | 备注 |
---|---|---|---|
@AssertTrue | boolean、Boolean | 为true | 为null有效 |
@AssertFalse | boolean、Boolean | 为false | 为null有效 |
日期检查
注解 | 支持Java类型 | 说明 | 备注 |
---|---|---|---|
@Future | Date、Calendar、Instant、LocalDate、LocalDateTime、LocalTime、MonthDay、OffsetDateTime、OffsetTime、Year、YearMonth、ZonedDateTime、HijrahDate、JapaneseDate、MinguoDate、ThaiBuddhistDate | 验证日期为当前时间之后 | 为null有效 |
@FutureOrPresent | Date、Calendar、Instant、LocalDate、LocalDateTime、LocalTime、MonthDay、OffsetDateTime、OffsetTime、Year、YearMonth、ZonedDateTime、HijrahDate、JapaneseDate、MinguoDate、ThaiBuddhistDate | 验证日期为当前时间或之后 | 为null有效 |
@Past | Date、Calendar、Instant、LocalDate、LocalDateTime、LocalTime、MonthDay、OffsetDateTime、OffsetTime、Year、YearMonth、ZonedDateTime、HijrahDate、JapaneseDate、MinguoDate、ThaiBuddhistDate | 验证日期为当前时间之前 | 为null有效 |
@PastOrPresent | Date、Calendar、Instant、LocalDate、LocalDateTime、LocalTime、MonthDay、OffsetDateTime、OffsetTime、Year、YearMonth、ZonedDateTime、HijrahDate、JapaneseDate、MinguoDate、ThaiBuddhistDate | 验证日期为当前时间或之前 | 为null有效 |
数值检查
注解 | 支持Java类型 | 说明 | 备注 |
---|---|---|---|
注解 | 支持Java类型 | 说明 | 备注 |
@Max | BigDecimal、BigInteger,byte、short、int、long以及包装类 | 小于或等于 | 为null有效 |
@Min | BigDecimal、BigInteger,byte、short、int、long以及包装类 | 大于或等于 | 为null有效 |
@DecimalMax | BigDecimal、BigInteger、CharSequence,byte、short、int、long以及包装类 | 小于或等于 | 为null有效 |
@DecimalMin | BigDecimal、BigInteger、CharSequence,byte、short、int、long以及包装类 | 大于或等于 | 为null有效 |
@Negative | BigDecimal、BigInteger,byte、short、int、long、float、double以及包装类 | 负数 | 为null有效,0无效 |
@NegativeOrZero | BigDecimal、BigInteger,byte、short、int、long、float、double以及包装类 | 负数或零 | 为null有效 |
@Positive | BigDecimal、BigInteger,byte、short、int、long、float、double以及包装类 | 正数 | 为null有效,0无效 |
@PositiveOrZero | BigDecimal、BigInteger,byte、short、int、long、float、double以及包装类 | 正数或零 | 为null有效 |
@Digits(integer = 3, fraction = 2) | BigDecimal、BigInteger、CharSequence,byte、short、int、long以及包装类 | 整数位数和小数位数上限 | 为null有效 |
其他
注解 | 支持Java类型 | 说明 | 备注 |
---|---|---|---|
@Pattern | CharSequence | 匹配指定的正则表达式 | 为null有效 |
CharSequence | 邮箱地址 | 为null有效,默认正则 '.*' | |
@Size | CharSequence、Collection、Map、Array | 大小范围(length/size>0) | 为null有效 |
hibernate-validator扩展约束(部分)
注解 | 支持Java类型 | 说明 |
---|---|---|
@Length | String | 字符串长度范围 |
@Range | 数值类型和String | 指定范围 |
@URL | URL地址验证 |