在 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=) | 被註釋的元素必須在合適的範圍內 |