13 changed files with 409 additions and 69 deletions
@ -0,0 +1,111 @@ |
|||||||
|
[[mvc-ann-validation]] |
||||||
|
= Validation |
||||||
|
|
||||||
|
[.small]#xref:web/webmvc/mvc-controller/ann-validation.adoc[See equivalent in the Servlet stack]# |
||||||
|
|
||||||
|
Spring WebFlux has built-in xref:core/validation/validator.adoc[Validation] support for |
||||||
|
`@RequestMapping` methods, including the option to use |
||||||
|
xref:core/validation/beanvalidation.adoc[Java Bean Validation]. |
||||||
|
The validation support works on two levels. |
||||||
|
|
||||||
|
First, method parameters such as |
||||||
|
xref:web/webflux/controller/ann-methods/modelattrib-method-args.adoc[@ModelAttribute], |
||||||
|
xref:web/webflux/controller/ann-methods/requestbody.adoc[@RequestBody], and |
||||||
|
xref:web/webflux/controller/ann-methods/multipart-forms.adoc[@RequestPart] do perform |
||||||
|
validation if annotated with Jakarta's `@Valid` or Spring's `@Validated` annotation, and |
||||||
|
raise `MethodArgumentNotValidException` in case of validation errors. If you want to handle |
||||||
|
the errors in the controller method instead, you can declare an `Errors` or `BindingResult` |
||||||
|
method parameter immediately after the validated parameter. |
||||||
|
|
||||||
|
Second, if https://beanvalidation.org/[Java Bean Validation] is present _AND_ other method |
||||||
|
parameters, e.g. `@RequestHeader`, `@RequestParam`, `@PathVariable` have `@Constraint` |
||||||
|
annotations, then method validation is applied to all method arguments, raising |
||||||
|
`HandlerMethodValidationException` in case of validation errors. You can still declare an |
||||||
|
`Errors` or `BindingResult` after an `@Valid` method parameter, and handle validation |
||||||
|
errors within the controller method, as long as there are no validation errors on other |
||||||
|
method arguments. |
||||||
|
|
||||||
|
You can configure a `Validator` globally through the |
||||||
|
xref:web/webflux/config.adoc#webflux-config-validation[WebMvc config], or locally |
||||||
|
through an xref:web/webflux/controller/ann-initbinder.adoc[@InitBinder] method in an |
||||||
|
`@Controller` or `@ControllerAdvice`. You can also use multiple validators. |
||||||
|
|
||||||
|
NOTE: If a controller has a class level `@Validated`, then |
||||||
|
xref:core/validation/beanvalidation.adoc#validation-beanvalidation-spring-method[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 |
||||||
|
`@Validated` annotation from the controller. |
||||||
|
|
||||||
|
The xref:web/webmvc/mvc-ann-rest-exceptions.adoc[Error Responses] section provides further |
||||||
|
details on how `MethodArgumentNotValidException` 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 of``ParameterValidationResult``s 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: |
||||||
|
|
||||||
|
[tabs] |
||||||
|
====== |
||||||
|
Java:: |
||||||
|
+ |
||||||
|
[source,java,indent=0,subs="verbatim,quotes",role="primary"] |
||||||
|
---- |
||||||
|
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) { |
||||||
|
// ... |
||||||
|
} |
||||||
|
}); |
||||||
|
---- |
||||||
|
|
||||||
|
Kotlin:: |
||||||
|
+ |
||||||
|
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"] |
||||||
|
---- |
||||||
|
// 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) { |
||||||
|
// ... |
||||||
|
} |
||||||
|
}) |
||||||
|
---- |
||||||
|
====== |
||||||
@ -0,0 +1,112 @@ |
|||||||
|
[[mvc-ann-validation]] |
||||||
|
= Validation |
||||||
|
|
||||||
|
[.small]#xref:web/webflux/controller/ann-validation.adoc[See equivalent in the Reactive stack]# |
||||||
|
|
||||||
|
Spring MVC has built-in xref:core/validation/validator.adoc[Validation] support for |
||||||
|
`@RequestMapping` methods, including the option to use |
||||||
|
xref:core/validation/beanvalidation.adoc[Java Bean Validation]. |
||||||
|
The validation support works on two levels. |
||||||
|
|
||||||
|
First, method parameters such as |
||||||
|
xref:web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.adoc[@ModelAttribute], |
||||||
|
xref:web/webmvc/mvc-controller/ann-methods/requestbody.adoc[@RequestBody], and |
||||||
|
xref:web/webmvc/mvc-controller/ann-methods/multipart-forms.adoc[@RequestPart] do perform |
||||||
|
validation if annotated with Jakarta's `@Valid` or Spring's `@Validated` annotation, and |
||||||
|
raise `MethodArgumentNotValidException` in case of validation errors. If you want to handle |
||||||
|
the errors in the controller method instead, you can declare an `Errors` or `BindingResult` |
||||||
|
method parameter immediately after the validated parameter. |
||||||
|
|
||||||
|
Second, if https://beanvalidation.org/[Java Bean Validation] is present _AND_ other method |
||||||
|
parameters, e.g. `@RequestHeader`, `@RequestParam`, `@PathVariable` have `@Constraint` |
||||||
|
annotations, then method validation is applied to all method arguments, raising |
||||||
|
`HandlerMethodValidationException` in case of validation errors. You can still declare an |
||||||
|
`Errors` or `BindingResult` after an `@Valid` method parameter, and handle validation |
||||||
|
errors within the controller method, as long as there are no validation errors on other |
||||||
|
method arguments. Method validation is also applied to the return value if the method |
||||||
|
is annotated with `@Valid` or has other `@Constraint` annotations. |
||||||
|
|
||||||
|
You can configure a `Validator` globally through the |
||||||
|
xref:web/webmvc/mvc-config/validation.adoc[WebMvc config], or locally through an |
||||||
|
xref:web/webmvc/mvc-controller/ann-initbinder.adoc[@InitBinder] method in an |
||||||
|
`@Controller` or `@ControllerAdvice`. You can also use multiple validators. |
||||||
|
|
||||||
|
NOTE: If a controller has a class level `@Validated`, then |
||||||
|
xref:core/validation/beanvalidation.adoc#validation-beanvalidation-spring-method[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 |
||||||
|
`@Validated` annotation from the controller. |
||||||
|
|
||||||
|
The xref:web/webmvc/mvc-ann-rest-exceptions.adoc[Error Responses] section provides further |
||||||
|
details on how `MethodArgumentNotValidException` 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 of``ParameterValidationResult``s 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: |
||||||
|
|
||||||
|
[tabs] |
||||||
|
====== |
||||||
|
Java:: |
||||||
|
+ |
||||||
|
[source,java,indent=0,subs="verbatim,quotes",role="primary"] |
||||||
|
---- |
||||||
|
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) { |
||||||
|
// ... |
||||||
|
} |
||||||
|
}); |
||||||
|
---- |
||||||
|
|
||||||
|
Kotlin:: |
||||||
|
+ |
||||||
|
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"] |
||||||
|
---- |
||||||
|
// 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) { |
||||||
|
// ... |
||||||
|
} |
||||||
|
}) |
||||||
|
---- |
||||||
|
====== |
||||||
Loading…
Reference in new issue