驗證
Spring WebFlux 具有內建的 驗證 功能,適用於 @RequestMapping
方法,包括 Java Bean 驗證。驗證可以應用於兩個層級之一
-
@ModelAttribute、@RequestBody 和 @RequestPart 引數解析器會個別驗證方法引數,如果方法參數使用 Jakarta
@Valid
或 Spring 的@Validated
進行註解,且 緊接在後沒有Errors
或BindingResult
參數,且 不需要方法驗證(稍後討論)。在這種情況下引發的例外是WebExchangeBindException
。 -
當
@Constraint
註解(例如@Min
、@NotBlank
和其他註解)直接在方法參數或方法上宣告(用於傳回值)時,則必須應用方法驗證,這會取代方法引數層級的驗證,因為方法驗證涵蓋方法參數限制和透過@Valid
的巢狀限制。在這種情況下引發的例外是HandlerMethodValidationException
。
應用程式必須處理 WebExchangeBindException
和 HandlerMethodValidationException
,因為這兩種例外都可能根據控制器方法簽章而引發。然而,這兩種例外都設計得非常相似,並且可以使用幾乎相同的程式碼進行處理。主要區別在於前者適用於單一物件,而後者適用於方法參數列表。
@Valid 不是限制註解,而是用於物件內的巢狀限制。因此,@Valid 本身不會導致方法驗證。另一方面,@NotNull 是一種限制,將其新增到 @Valid 參數會導致方法驗證。對於空值性,您也可以使用 @RequestBody 或 @ModelAttribute 的 required 標誌。 |
方法驗證可以與 Errors
或 BindingResult
方法參數結合使用。但是,只有當所有驗證錯誤都位於緊接在後的 Errors
方法參數上時,才會呼叫控制器方法。如果任何其他方法參數上存在驗證錯誤,則會引發 HandlerMethodValidationException
。
您可以透過 WebFlux 配置 全域配置 Validator
,或透過 @Controller
或 @ControllerAdvice
中的 @InitBinder 方法在本機配置。您也可以使用多個驗證器。
如果控制器具有類別層級的 @Validated ,則 方法驗證會透過 AOP 代理應用。為了利用 Spring Framework 6.1 中新增的 Spring MVC 內建方法驗證支援,您需要從控制器中移除類別層級的 @Validated 註解。 |
錯誤回應 區段提供關於如何處理 WebExchangeBindException
和 HandlerMethodValidationException
的更多詳細資訊,以及如何透過 MessageSource
和地區設定與語言特定的資源束來自訂其呈現方式。
為了進一步自訂方法驗證錯誤的處理方式,您可以擴充 ResponseEntityExceptionHandler
或在控制器或 @ControllerAdvice
中使用 @ExceptionHandler
方法,並直接處理 HandlerMethodValidationException
。例外包含 ParameterValidationResult
列表,這些列表依方法參數對驗證錯誤進行分組。您可以逐一查看這些列表,或依控制器方法參數類型提供具有回呼方法的訪問器
-
Java
-
Kotlin
HandlerMethodValidationException ex = ... ;
ex.visitResults(new HandlerMethodValidationException.Visitor() {
@Override
public void requestHeader(RequestHeader requestHeader, ParameterValidationResult result) {
// ...
}
@Override
public void requestParam(@Nullable RequestParam requestParam, ParameterValidationResult result) {
// ...
}
@Override
public void modelAttribute(@Nullable ModelAttribute modelAttribute, ParameterErrors errors) {
// ...
@Override
public void other(ParameterValidationResult result) {
// ...
}
});
// HandlerMethodValidationException
val ex
ex.visitResults(object : HandlerMethodValidationException.Visitor {
override fun requestHeader(requestHeader: RequestHeader, result: ParameterValidationResult) {
// ...
}
override fun requestParam(requestParam: RequestParam?, result: ParameterValidationResult) {
// ...
}
override fun modelAttribute(modelAttribute: ModelAttribute?, errors: ParameterErrors) {
// ...
}
// ...
override fun other(result: ParameterValidationResult) {
// ...
}
})