驗證

Spring WebFlux 具有內建的 驗證 功能,適用於 @RequestMapping 方法,包括 Java Bean 驗證。驗證可以應用於兩個層級之一

  1. @ModelAttribute@RequestBody@RequestPart 引數解析器會個別驗證方法引數,如果方法參數使用 Jakarta @Valid 或 Spring 的 @Validated 進行註解, 緊接在後沒有 ErrorsBindingResult 參數, 不需要方法驗證(稍後討論)。在這種情況下引發的例外是 WebExchangeBindException

  2. @Constraint 註解(例如 @Min@NotBlank 和其他註解)直接在方法參數或方法上宣告(用於傳回值)時,則必須應用方法驗證,這會取代方法引數層級的驗證,因為方法驗證涵蓋方法參數限制和透過 @Valid 的巢狀限制。在這種情況下引發的例外是 HandlerMethodValidationException

應用程式必須處理 WebExchangeBindExceptionHandlerMethodValidationException,因為這兩種例外都可能根據控制器方法簽章而引發。然而,這兩種例外都設計得非常相似,並且可以使用幾乎相同的程式碼進行處理。主要區別在於前者適用於單一物件,而後者適用於方法參數列表。

@Valid 不是限制註解,而是用於物件內的巢狀限制。因此,@Valid 本身不會導致方法驗證。另一方面,@NotNull 是一種限制,將其新增到 @Valid 參數會導致方法驗證。對於空值性,您也可以使用 @RequestBody@ModelAttributerequired 標誌。

方法驗證可以與 ErrorsBindingResult 方法參數結合使用。但是,只有當所有驗證錯誤都位於緊接在後的 Errors 方法參數上時,才會呼叫控制器方法。如果任何其他方法參數上存在驗證錯誤,則會引發 HandlerMethodValidationException

您可以透過 WebFlux 配置 全域配置 Validator,或透過 @Controller@ControllerAdvice 中的 @InitBinder 方法在本機配置。您也可以使用多個驗證器。

如果控制器具有類別層級的 @Validated,則 方法驗證會透過 AOP 代理應用。為了利用 Spring Framework 6.1 中新增的 Spring MVC 內建方法驗證支援,您需要從控制器中移除類別層級的 @Validated 註解。

錯誤回應 區段提供關於如何處理 WebExchangeBindExceptionHandlerMethodValidationException 的更多詳細資訊,以及如何透過 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) {
			// ...
       }
})