注意: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 规范,即:-api(现为 -api,jar 包的名字改变,包里面的包名、类名未变,因此使用方式不变)包,spring-boot-starter-web
、spring-boot-starter-webflux
包都已引入此依赖,直接使用即可。
有点类似于 slf4j 与 logback(log4j2)的关系,使用的时候,代码中使用 提供的接口规范功能,加载的时候,根据 SPI 规范加载对应的规范实现类。
它和 hibernate
没什么关系,放心大胆的使用吧。
引入依赖
首先,我们在 Maven 配置中引入 @valid 的依赖:
如果你是 springboot 项目,那么可以不用引入了,已经引入了,他就存在于最核心的 web 开发包里面。
<dependency>
<groupId></groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.0.</version>
</dependency>
如果你不是 springboot 项目,那么引入下面依赖即可:
<dependency>
<groupId></groupId>
<artifactId>validation-api</artifactId>
<version>1.1.</version>
</dependency>
<dependency>
<groupId></groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.4.</version>
</dependency>
标识注解
@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 的任意子类, 的任意子类
@Min(value=)
检查值是否大于或等于指定的最大值
支持的数据类型:
BigDecimal, BigInteger, byte, short, int, long, 原生类型的封装类, CharSequence 的任意子类(字符序列表示的数字), Number 的任意子类, 的任意子类
@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 的任意子类, 的任意子类
@NegativeOrZero
检查元素是否为负或零。
支持数据类型:
BigDecimal, BigInteger, byte, short, int, long, 原生类型的封装类, CharSequence 的任意子类(字符序列表示的数字), Number 的任意子类, 的任意子类
@Positive
检查元素是否严格为正。零值被视为无效。
支持数据类型:
BigDecimal, BigInteger, byte, short, int, long, 原生类型的封装类, CharSequence 的任意子类(字符序列表示的数字), Number 的任意子类, 的任意子类
@PositiveOrZero
检查元素是否为正或零。
支持数据类型:
BigDecimal, BigInteger, byte, short, int, long, 原生类型的封装类, CharSequence 的任意子类(字符序列表示的数字), Number 的任意子类, 的任意子类
@Null
检查值是否为 null
支持数据类型:任何类型
@Future
检查日期是否在未来
支持的数据类型:
, , , , , , , , , , , , , , ,
如果 Joda Time API 在类路径中,ReadablePartial
和ReadableInstant
的任何实现类
@FutureOrPresent
检查日期是现在或将来
支持数据类型:同@Future
@Past
检查日期是否在过去
支持数据类型:同@Future
@PastOrPresent
检查日期是否在过去或现在
支持数据类型:同@Future
@Pattern(regex=, flags=)
根据给定的 flag
匹配,检查字符串是否与正则表达式 regex
匹配
支持数据类型:CharSequence
使用实例
自定义ValidatorUtils
public class ValidatorUtils {
private static Validator validator;
// 初始化 validator
static {
validator = ().getValidator();
}
/**
* 校验数据
*
* @param object
* @param groups
*/
public static void validateEntity(Object object, Class<?>... groups) {
Set<ConstraintViolation<Object>> constraintViolations = null;
try {
constraintViolations = (object, groups);
} catch (Exception e) {
();
throw new ApiException("校验失败!");
}
if (!()) {
Iterator<ConstraintViolation<Object>> iterator = ();
StringBuffer sb = new StringBuffer();
while (()) {
ConstraintViolation<Object> constraint = ();
(getMsg(()));
if (()) {
(",");
}
}
throw new ApiException(());
}
}
private static String getMsg(String code) {
try {
return (code);
} catch (Exception e) {
return code;
}
}
}
示例
/** 省略代码 **/
public ApiResult add(@Valid @RequestBody SysUser user,BindingResult result) {
if(()){
StringBuilder msg = new StringBuilder();
for (ObjectError error : ()) {
(()+"\n");
}
return error(());
}
return toApi((user));
}
public ApiResult add1(@Validated @RequestBody SysUser user) {
return toApi((user));
}
public ApiResult add2(@RequestBody ComUser bo) {
(bo, );
return toApi((bo));
}
/** 省略代码 **/