温馨提示
请收藏再看。此文篇幅太长,你短时间看不完;此文干货太多,错过太可惜。
示例代码可以关注逸飞兮
(公众号)回复jy
获取。
收获
- 讲解详细:能让你掌握使用
hibernate-validator
及类似校验工具的各种使用姿势 - 内容全面:可以当做知识字典来查询
what
注意:hibernate-validator 与 持久层框架 hibernate
没有什么关系,hibernate-validator 是 hibernate 组织下的一个开源项目 。
hibernate-validator
是 JSR 380(Bean Validation 2.0)
、JSR 303(Bean Validation 1.0)
规范的实现。
JSR 380
- Bean Validation 2.0
定义了一个实体和方法验证的元数据模型和 API。
JavaEE(改名为:Jakarta EE)中制定了 validation 规范,即:javax.validation-api(现为 jakarta.validation-api,jar 包的名字改变,包里面的包名、类名未变,因此使用方式不变)包,spring-boot-starter-web
、spring-boot-starter-webflux
包都已引入此依赖,直接使用即可。
有点类似于 slf4j 与 logback(log4j2)的关系,使用的时候,代码中使用 javax.validate
提供的接口规范功能,加载的时候,根据 SPI 规范加载对应的规范实现类。
它和 hibernate
没什么关系,放心大胆的使用吧。
why
hibernate-validator 官方有如下说明:
以前的校验如下:
使用 hibernate-validator
后,校验逻辑如下:
controller、service、dao 层相同的校验逻辑可以使用同一个数据校验模型。
how
标识注解
@Valid(规范、常用)
标记用于验证
级联
的属性、方法参数或方法返回类型。在验证属性、方法参数或方法返回类型时,将验证在对象及其属性上定义的约束。
此行为是
递归
应用的。
@Validated(spring)
spring
提供的扩展注解,可以方便的用于分组校验
22 个约束注解
下面除了列出的参数,每个约束都有参数 message,groups 和 payload。这是 Bean Validation 规范的要求。
其中,message
是提示消息,groups
可以根据情况来分组。
以下每一个注解都可以在相同元素上定义多个。
@AssertFalse
检查元素是否为 false,支持数据类型:boolean、Boolean
@AssertTrue
检查元素是否为 true,支持数据类型:boolean、Boolean
@DecimalMax(value=, inclusive=)
inclusive:boolean,默认 true,表示是否包含,是否等于value:当 inclusive=false 时,检查带注解的值是否小于指定的最大值。当 inclusive=true 检查该值是否小于或等于指定的最大值。参数值是根据 bigdecimal 字符串表示的最大值。支持数据类型:BigDecimal、BigInteger、CharSequence、(byte、short、int、long 和其封装类)
@DecimalMin(value=, inclusive=)
支持数据类型:BigDecimal、BigInteger、CharSequence、(byte、short、int、long 和其封装类)inclusive:boolean,默认 true,表示是否包含,是否等于value:当 inclusive=false 时,检查带注解的值是否大于指定的最大值。当 inclusive=true 检查该值是否大于或等于指定的最大值。参数值是根据 bigdecimal 字符串表示的最小值。
@Digits(integer=, fraction=)
检查值是否为最多包含 integer
位整数和 fraction
位小数的数字支持的数据类型:BigDecimal, BigInteger, CharSequence, byte, short, int, long 、原生类型的封装类、任何 Number 子类。
检查指定的字符序列是否为有效的电子邮件地址。可选参数 regexp
和 flags
允许指定电子邮件必须匹配的附加正则表达式(包括正则表达式标志)。支持的数据类型:CharSequence
@Max(value=)
检查值是否小于或等于指定的最大值支持的数据类型:BigDecimal, BigInteger, byte, short, int, long, 原生类型的封装类, CharSequence 的任意子类(字符序列表示的数字), Number 的任意子类, javax.money.MonetaryAmount 的任意子类
@Min(value=)
检查值是否大于或等于指定的最大值支持的数据类型:BigDecimal, BigInteger, byte, short, int, long, 原生类型的封装类, CharSequence 的任意子类(字符序列表示的数字), Number 的任意子类, javax.money.MonetaryAmount 的任意子类
@NotBlank
检查字符序列是否为空,以及去空格后的长度是否大于 0。与 @NotEmpty
的不同之处在于,此约束只能应用于字符序列,并且忽略尾随空格。支持数据类型:CharSequence
@NotNull
检查值是否不为 null
支持数据类型:任何类型
@NotEmpty
检查元素是否为 null
或 空
支持数据类型:CharSequence, Collection, Map, arrays
@Size(min=, max=)
检查元素个数是否在 min(含)和 max(含)之间支持数据类型:CharSequence,Collection,Map, arrays
@Negative
检查元素是否严格为负数。零值被认为无效。支持数据类型:BigDecimal, BigInteger, byte, short, int, long, 原生类型的封装类, CharSequence 的任意子类(字符序列表示的数字), Number 的任意子类, javax.money.MonetaryAmount 的任意子类
@NegativeOrZero
检查元素是否为负或零。支持数据类型:BigDecimal, BigInteger, byte, short, int, long, 原生类型的封装类, CharSequence 的任意子类(字符序列表示的数字), Number 的任意子类, javax.money.MonetaryAmount 的任意子类
@Positive
检查元素是否严格为正。零值被视为无效。支持数据类型:BigDecimal, BigInteger, byte, short, int, long, 原生类型的封装类, CharSequence 的任意子类(字符序列表示的数字), Number 的任意子类, javax.money.MonetaryAmount 的任意子类
@PositiveOrZero
检查元素是否为正或零。支持数据类型:BigDecimal, BigInteger, byte, short, int, long, 原生类型的封装类, CharSequence 的任意子类(字符序列表示的数字), Number 的任意子类, javax.money.MonetaryAmount 的任意子类
@Null
检查值是否为 null
支持数据类型:任何类型
@Future
检查日期是否在未来支持的数据类型:java.util.Date, java.util.Calendar, java.time.Instant, java.time.LocalDate, java.time.LocalDateTime, java.time.LocalTime, java.time.MonthDay, java.time.OffsetDateTime, java.time.OffsetTime, java.time.Year, java.time.YearMonth, java.time.ZonedDateTime, java.time.chrono.HijrahDate, java.time.chrono.JapaneseDate, java.time.chrono.MinguoDate, java.time.chrono.ThaiBuddhistDate如果 Joda Time API 在类路径中,ReadablePartial
和ReadableInstant
的任何实现类
@FutureOrPresent
检查日期是现在或将来支持数据类型:同@Future
@Past
检查日期是否在过去支持数据类型:同@Future
@PastOrPresent
检查日期是否在过去或现在支持数据类型:同@Future
@Pattern(regex=, flags=)
根据给定的 flag
匹配,检查字符串是否与正则表达式 regex
匹配支持数据类型:CharSequence
实现示例
@Size
从上文可知,规范中,@Size 支持的数据类型有:CharSequence,Collection,Map, arrayshibernate-validator 中的实现如下:
针对 CharSequence、Collection、Map 都有一个实现,由于 arrays 有多种可能,提供了多个实现。其中,SizeValidatorForCollection.java 如下:
import java.lang.invoke.MethodHandles;
import java.util.Collection;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.constraints.Size;
@SuppressWarnings("rawtypes")
// as per the JLS, Collection<?> is a subtype of Collection, so we need to explicitly reference
// Collection here to support having properties defined as Collection (see HV-1551)
public class SizeValidatorForCollection implements ConstraintValidator<Size, Collection> {
private static final Log LOG = LoggerFactory.make( MethodHandles.lookup() );
private int min;
private int max;
@Override
public void initialize(Size parameters) {
min = parameters.min();
max = parameters.max();
validateParameters();
}
@O