Spring Boot 参数校验 hibernate-validator @Valid 与 @Validated
在 Java 的 JSR303 标准中声明了 @Valid 该类参数校验接口,而 hibernate-validator 则是其中一个实现之一,它提供了一套比较完善、便捷的验证方式,并集成到了 spring-boot-starter-web 包中。java
快速上手
建立查询对象 UserQuerygit
@Data
public class ValidDemoQuery{
private String name;
@Pattern(regexp = "admin|member", message = "角色必须为admin或member")
private String role;
@Min(value = 1, message = "年龄必须大于1岁!")
private String age;
}
复制代码
GET 接口对查询对象进行验证web
@RestController
@RequestMapping("demo/valid")
@Payload
public class ValidDemoController{
@GetMapping
public String valid(@Valid ValidDemoQuery query){
return "success";
}
}
复制代码
执行请求正则表达式
curl http://127.0.0.1:8080/deepexi-dubbo/demo/valid?age=0&role=developer
#错误信息
角色必须为admin或member
年龄必须大于1岁!
复制代码
校验模式
普通模式(默认):在普通模式下,会校验完全部的属性,而后返回全部验证失败信息。spring
快速失败模式:只要有一个验证失败,则返回。切换为快速失败模式可参考下面代码:shell
@Configuration
public class ValidatorConfiguration{
@Bean
public Validator validator(){
ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )
.configure()
.addProperty( "hibernate.validator.fail_fast", "true" )
.buildValidatorFactory();
Validator validator = validatorFactory.getValidator();
return validator;
}
}
复制代码
校验失败处理
在使用 @Valid 注解的参数后能够紧跟着一个 BindingResult 类型的参数,用于获取校验结果,不然 Spring 会在校验不经过时抛出异常。bash
@GetMapping
public String valid(@Valid ValidDemoQuery query, BindingResult result){
if (result.hasErrors()) {
for (FieldError fieldError : result.getFieldErrors()) {
System.out.println(fieldError.getDefaultMessage());
}
return "fail";
}
return "success";
}
复制代码
若是有多个参数须要进行校验,能够添加多个 @Valid 与 BindingResult。如:app
public String valid(@Valid ValidDemoQuery query1, BindingResult result1,@Valid ValidDemoQuery query2, BindingResult result2){}
复制代码
嵌套校验
对象内部包含另外一个对象做为属性,属性上加 @Valid,能够验证做为属性的对象内部的验证。框架
@Data
public class ValidDemoQuery{
private String name;
@Valid
private RoleDemoQuery role;
@Min(value = 1, message = "年龄必须大于1岁!")
private String age;
@Data
public class RoleDemoQuery{
@Pattern(regexp = "admin|member", message = "角色必须为admin或member")
private String role;
}
}
复制代码
@Validated
Spring Validation 验证框架对参数校验提供了 @Validated 支持,它还能够与 JSR303 的 @Valid 同时使用,提供更丰富的参数校验。curl
并提供了一个分组功能,能够在入参验证时,根据不一样分组采用不一样的验证机制。
对入参基本数据类型校验
@RestController
@RequestMapping("demo/valid")
@Payload
@Validated
public class ValidDemoController{
@GetMapping
public String valid(@Min(value = 1,message = "年龄必须大于1") Integer age){
return "success";
}
}
复制代码
执行请求
curl http://127.0.0.1:8080/deepexi-dubbo/demo/valid?age=0
#错误信息
test.age: 年龄必须大于1
复制代码
分组校验
经过注解的 groups 属性能够指定该校验属于一个或多个分组
@Data
public class ValidDemoQuery{
private String name;
@Pattern(regexp = "admin|member", message = "角色必须为admin或member", groups = {Role.class})
private String role;
@Min(value = 1, message = "年龄必须大于1岁!")
private String age;
public interface Role{}
}
复制代码
仅在 Role 分组下,role 字段的参数校验才会起效
@GetMapping
public String valid(@Validated(ValidDemoQuery.Role.class) ValidDemoQuery query, BindingResult result){
if (result.hasErrors()) {
for (FieldError fieldError : result.getFieldErrors()) {
System.out.println(fieldError.getDefaultMessage());
}
return "fail";
}
return "success";
}
复制代码
经常使用注解
注解
做用
@Null
被注释的元素必须为 null
@NotNull
被注释的元素必须不为 null
@AssertTrue
被注释的元素必须为 true
@AssertFalse
被注释的元素必须为 false
@Min(value)
被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value)
被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value)
被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value)
被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max=, min=)
被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction)
被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past
被注释的元素必须是一个过去的日期
@Future
被注释的元素必须是一个未来的日期
@Pattern(regex=,flag=)
被注释的元素必须符合指定的正则表达式
@NotBlank(message =)
验证字符串非 null,且长度必须大于 0
被注释的元素必须是电子邮箱地址
@Length(min=,max=)
被注释的字符串的大小必须在指定的范围内
@NotEmpty
被注释的字符串的必须非空
@Range(min=,max=,message=)
被注释的元素必须在合适的范围内