Spring Boot 參數校驗 hibernate-validator @Valid 與 @Validated

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
@Email 被註釋的元素必須是電子郵箱地址
@Length(min=,max=) 被註釋的字符串的大小必須在指定的範圍內
@NotEmpty 被註釋的字符串的必須非空
@Range(min=,max=,message=) 被註釋的元素必須在合適的範圍內
相關文章
相關標籤/搜索