| For the latest stable version, please use Spring Framework 6.2.12! | 
Validation
Spring WebFlux has built-in Validation for
@RequestMapping methods, including Java Bean Validation.
Validation may be applied at one of two levels:
- 
@ModelAttribute, @RequestBody, and @RequestPart argument resolvers validate a method argument individually if the method parameter is annotated with Jakarta @Validor Spring’s@Validated, AND there is noErrorsorBindingResultparameter immediately after, AND method validation is not needed (to be discussed next). The exception raised in this case isWebExchangeBindException.
- 
When @Constraintannotations such as@Min,@NotBlankand others are declared directly on method parameters, or on the method (for the return value), then method validation must be applied, and that supersedes validation at the method argument level because method validation covers both method parameter constraints and nested constraints via@Valid. The exception raised in this case isHandlerMethodValidationException.
Applications must handle both WebExchangeBindException and
HandlerMethodValidationException as either may be raised depending on the controller
method signature. The two exceptions, however are designed to be very similar, and can be
handled with almost identical code. The main difference is that the former is for a single
object while the latter is for a list of method parameters.
| @Validis not a constraint annotation, but rather for nested constraints within
an Object. Therefore, by itself@Validdoes not lead to method validation.@NotNullon the other hand is a constraint, and adding it to an@Validparameter leads to method
validation. For nullability specifically, you may also use therequiredflag of@RequestBodyor@ModelAttribute. | 
Method validation may be used in combination with Errors or BindingResult method
parameters. However, the controller method is called only if all validation errors are on
method parameters with an Errors immediately after. If there are validation errors on
any other method parameter then HandlerMethodValidationException is raised.
You can configure a Validator globally through the
WebFlux config, or locally
through an @InitBinder method in an
@Controller or @ControllerAdvice. You can also use multiple validators.
| If a controller has a class level @Validated, then
method validation is applied
through an AOP proxy. In order to take advantage of the Spring MVC built-in support for
method validation added in Spring Framework 6.1, you need to remove the class level@Validatedannotation from the controller. | 
The Error Responses section provides further
details on how WebExchangeBindException and HandlerMethodValidationException
are handled, and also how their rendering can be customized through a MessageSource and
locale and language specific resource bundles.
For further custom handling of method validation errors, you can extend
ResponseEntityExceptionHandler or use an @ExceptionHandler method in a controller
or in a @ControllerAdvice, and handle HandlerMethodValidationException directly.
The exception contains a list ofParameterValidationResults that group validation errors
by method parameter. You can either iterate over those, or provide a visitor with callback
methods by controller method parameter type:
- 
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) {
			// ...
       }
})