驗證
Spring MVC 內建 驗證,適用於 @RequestMapping
方法,包括 Java Bean 驗證。驗證可以應用於兩個層級之一
-
@ModelAttribute、@RequestBody 和 @RequestPart 引數解析器會在方法參數標註 Jakarta
@Valid
或 Spring 的@Validated
時,個別驗證方法引數,且 後面沒有緊接著Errors
或BindingResult
參數,且 不需要方法驗證(稍後討論)。在這種情況下引發的例外是MethodArgumentNotValidException
。 -
當
@Constraint
註解(例如@Min
、@NotBlank
等)直接在方法參數或方法上宣告時(用於傳回值),則必須應用方法驗證,並且方法驗證會取代方法引數層級的驗證,因為方法驗證涵蓋方法參數約束和透過@Valid
的巢狀約束。在這種情況下引發的例外是HandlerMethodValidationException
。
應用程式必須處理 MethodArgumentNotValidException
和 HandlerMethodValidationException
,因為取決於控制器方法簽章,兩者都可能被引發。然而,這兩個例外旨在非常相似,並且可以使用幾乎相同的程式碼來處理。主要區別在於前者用於單一物件,而後者用於方法參數列表。
@Valid 不是約束註解,而是用於物件內的巢狀約束。因此,@Valid 本身不會導致方法驗證。另一方面,@NotNull 是一種約束,將其新增至 @Valid 參數會導致方法驗證。針對空值安全性,您也可以使用 @RequestBody 或 @ModelAttribute 的 required 旗標。 |
方法驗證可以與 Errors
或 BindingResult
方法參數結合使用。但是,只有在所有驗證錯誤都位於緊接在後的 Errors
方法參數上時,才會呼叫控制器方法。如果任何其他方法參數存在驗證錯誤,則會引發 HandlerMethodValidationException
。
您可以透過 WebMvc 組態 全域組態 Validator
,或透過 @Controller
或 @ControllerAdvice
中的 @InitBinder 方法在本機組態。您也可以使用多個驗證器。
如果控制器具有類別層級 @Validated ,則 方法驗證會透過 AOP Proxy 應用。為了利用 Spring Framework 6.1 中新增的 Spring MVC 內建方法驗證支援,您需要從控制器中移除類別層級 @Validated 註解。 |
錯誤回應 章節提供了關於如何處理 MethodArgumentNotValidException
和 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) {
// ...
}
})