SpringBoot 中使用 Validation 校驗參數的方法詳解

項目中寫邏輯時,為保證程序的健壯性,需要對各種參數進行判斷,這就導致業務代碼不隻健壯,還十分臃腫。其實 SpringBoot 中已經提供瞭 Validation 參數驗證框架,可以方便的對參數進行合法性校驗。

1. Validation 介紹

Validation 是用於檢查程序代碼中參數的有效性的框架,作為 Spring 框架中的一個參數校驗工具,集成在 spring-context 包中。

1.1 Validation 註解

Validation 包含瞭眾多的註解來幫助對Java程序不同類型的參數進行校驗,校驗相關註解分佈在spring-boot-starter-validation 依賴的 javax.validation.constraints 包中。

  • @Null/@NotnULL,標註的字段必須為null/必須不為null
  • @AssertFalse/@AssertTrue,標註字段可以為null,但不為null時必須為false/true
  • @Email,標註的字段對應值必須為email格式
  • @URL,標註的字段值必須是URL
  • @Patten,標註的字段值必須符合定義的正則表達式

其他類似註解的使用可以查看javax.validation.constraints 包中定義註解信息。

1.2 @valid 和 @validated的區別

在實際使用 Validation 框架時,經常會對 @valid 和 @validated 註解的使用產生誤解,在這裡對比一下兩個註解的異同。

  • 當使用僅是註解字段屬性並驗證規范,@Validated 和 @Valid 註解的功能是相同的。
  • Spring Validation 驗證框架提供瞭 @Validated 註解對參數進行驗證,符合Spring’s JSR-303規范;而 @Valid 註解是 javax 提供的,符合標準的JSR-303規范。

在註解的使用上,@Validated 註解可以用於類型、方法和參數上;而 @Valid 還可以用於屬性之上。

//@Validated定義
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Validated {
    Class<?>[] value() default {};
}
//@Valid定義
@Target({ METHOD, FIELD, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Documented
public @interface Valid {
}
  • @Validated 註解可以使用分組校驗的功能,為同一個對象屬性提供不同分組,並根據分組來校驗屬性參數;而 @Valid 註解不支持分組驗證。
  • @Valid 註解支持嵌套驗證,當類的屬性是一個復雜對象時,可以使用 @Valid 對該屬性對象中的屬性同時進行校驗;@Validated 並不支持在屬性上使用。

2. SpringBoot 中使用 Validator 校驗參數

2.1 依賴引入

SpringBoot 中使用 Validator 無需單獨引入,因為在 web 依賴包中已經存在,直接使用即可。

<!-- starter web -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

如果 SpringBoot 版本比較新,在 web 包中可能已不再包含 Validation 框架,本地使用SpringBoot 2.6.3 版本 web 依賴包已經不再包含。

或者

SpringBoot新版本雖然不在web包中包含,但也提供瞭start啟動依賴提供相關功能,單獨引入 Jar 包可以使用如下坐標信息:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

另外,引入依賴時還可以引入 hibernate 提供的 validator框架包,不過使用時需要表明版本號信息。

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.1.5.Final</version>
</dependency>

2.2 標註校驗實體類

後端接收請求參數時,通常是使用 JavaBean 對象來接收參數信息,如果想要對實體類中的屬性進行校驗,則需要對屬性使用校驗相關的註解標註,並且實體對象必須定義 getter/setter方法,可以使用 lombok 的 @Data。

@Data
public class Customer{
    private Long id;
    @NotNull
    private String countryName;
    @NotNull
    private String countryCode;
    @Email
    private String email;
    @Valid
    private Customer parentCustomerInfo;
}

2.3 開啟參數校驗

2.3.1 簡單參數校驗

服務接口接收單個簡單參數時,可以在方法參數中直接使用校驗註解。

@PostMapping("/get")
public ResultMap getCustomerInfo(@RequestParam("customerCode") @NotNull(message = "用戶編碼不可以為空!") String customerCode){
    return ResultMapUtils().ok();
}

單參數校驗時,還需要在 controller 層控制器類中使用 @Validated 標註才會生效。

2.3.2 JavaBean 校驗

在實體類中使用校驗註解標註需要校驗的字段後,還需要在請求層接收參數時開啟參數校驗,隻需要在 controller 接口層的參數中使用 @Validated 標註,在接口接收到請求參數時會自動進行校驗。

@Autowired
private CustomerService customerService;
@PostMapping("/execute")
public ResultMap execute(@RequestBody @Validated GeneralDataRequest<CustomerRequest> generalDataRequest){
    CustomerRequest request = generalDataRequest.getData();
    return customerService.execute(request);
}

2.4 捕捉參數校驗異常

使用 Validation 校驗異常後,當參數發生異常時,會拋出 MethodArgumentNotValidException 類型的異常,為瞭程序報錯更通俗易懂,可以定義全局異常來捕獲該類型的異常,並統一返回結果信息。

@SLF4j
@ControllerAdvice
public class ExceptionConfig {
    /**
     * 參數校驗異常
     */
    @ResponseBody
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public ResultMap argumentExceptionHandler(MethodArgumentNotValidException exception) {
        String message = exception.getBindingResult().getFieldError().getDefaultMessage();
        log.info("發生參數異常:{}", message);
        return ResultMapUtils.resultError(ErrorCodeConstant.System.E100003, null, message);
    }
}

到此這篇關於SpringBoot 中使用 Validation 校驗參數的文章就介紹到這瞭,更多相關SpringBoot Validation 校驗參數內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: