在 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;
}
}
复制代码
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=) | 被注释的元素必须在合适的范围内 |