POM依赖
<!-- dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency -->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.13.Final</version>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>3.0.1-b06</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.el</artifactId>
<version>2.2.6</version>
</dependency>
注:hibernate-validator-6.0.13.Final
本身依赖validation-api
的版本即是2.0.1.Final
,若无冲突,则无需单独显式依赖validation-api-2.0.1.Final
初始化Validator
ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
.configure()
.failFast(true) // 是否仅输出第一个校验失败的信息
.buildValidatorFactory();
Validator validator = validatorFactory.getValidator();
上面的.failFast(true)
也可用.addProperty("hibernate.validator.fail_fast", "true")
替代,若是用的defaultProvider,即Validation.byDefaultProvider()
,则只能使用后者
校验接口方法入参
Set<ConstraintViolation<Object>> constraintViolationSet = validator.forExecutables().validateParameters(bean, method, args);
if (constraintViolationSet.isEmpty()) {
return null;
}
StringBuilder errorMsg = new StringBuilder();
for (ConstraintViolation violation : constraintViolationSet) {
errorMsg.append(";");
errorMsg.append(violation.getMessage());
}
return errorMsg.substring(1);
- 也可使用
validator.validate(arg)
来遍历校验单个参数,但要求arg
不能为null
,有些接口方法是平铺入参,且部分入参可为null
的则不适应 - 校验入口可放在AOP或Filter中使用
使用示例
入参类
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
public class User {
@NotBlank(message = "名称不能为空")
private String name;
@NotNull(message = "年龄不能为空")
@Min(value = 1, message = "年龄不能小于{value}")
private Integer age;
// .... getters and setters
}
接口方法
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
public interface UserService {
void register1(@Valid @NotNull(message = "请求入参不能为空") User user);
void register2(@NotBlank(message = "名称不能为空") String name, Integer age);
}
注:若入参是个大参数,如register1的入参,则必须加@Valid
注解,否则大参数里的属性不会校验
FAQ
若不指定校验失败的message,则会返回什么
若不指定message,则会返回默认的message,即注解的message默认值,如@NotNull
注解默认message占位符是{javax.validation.constraints.NotNull.message}
,如下图
根据占位符可搜索到在hibernate-validator
包下的Resource配置文件中,如下图
里面有对应的中文版本,如下图
上图上有各种语言版本,针对中文版的内容使用ASCII码,可通过工具转成native查看具体的message。
报错“Caused by: java.lang.NoClassDefFoundError: org/hibernate/validator/internal/engine/DefaultClockProvider”
原因是包冲突,根本原因是引入hibernate-validator依赖包后出现了validation-api的1.1.0.Final版本,应用中依赖的spring-boot中声明了validation-api-1.1.0.Final
包,所以在引入时出现了冲突。解决:可以显示在parent的POM中显示依赖validation-api-2.0.1.Final
即可。
报错“”
原因是没有依赖el相关包,增加如下包依赖即可
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>3.0.1-b06</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.el</artifactId>
<version>2.2.6</version>
</dependency>
TO BE CONTINUED...
- config bean
- spring-boot-starter-validation