From ac11b03cd3c37121232d0b556fe642103179cdc9 Mon Sep 17 00:00:00 2001 From: rstoyanchev Date: Fri, 7 Jul 2023 21:31:58 +0100 Subject: [PATCH] Document customization of method validation errors Closes gh-30653 --- .../pages/core/validation/beanvalidation.adoc | 94 +++++++++++++++++-- .../web/webflux/ann-rest-exceptions.adoc | 8 ++ .../web/webmvc/mvc-ann-rest-exceptions.adoc | 7 ++ 3 files changed, 101 insertions(+), 8 deletions(-) diff --git a/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc b/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc index b8fb73812823..4f782101064b 100644 --- a/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc +++ b/framework-docs/modules/ROOT/pages/core/validation/beanvalidation.adoc @@ -329,6 +329,16 @@ xref:core/aop/proxying.adoc#aop-understanding-aop-proxies[Understanding AOP Prox to always use methods and accessors on proxied classes; direct field access will not work. ==== +NOTE: Spring MVC and WebFlux have built-in support for method validation, and therefore +for web controller methods there is no need for a class level `@Validated` and an AOP proxy. +See the Spring MVC xref:web/webmvc/mvc-controller/ann-validation.adoc[Validation] section, +the WebFlux xref:web/webflux/controller/ann-validation.adoc[Validation] section, +and the xref:web/webmvc/mvc-controller/ann-validation.adoc[Error Responses] section. + + +[[validation-beanvalidation-spring-method-exceptions]] +==== Method Validation Exceptions + By default, `jakarta.validation.ConstraintViolationException` is raised with the set of ``ConstraintViolation``s returned by `jakarata.validation.Validator`. As an alternative, you can have `MethodValidationException` raised instead with ``ConstraintViolation``s @@ -373,18 +383,86 @@ fields and properties, the `ParameterValidationResult` is `ParameterErrors` whic implements `org.springframework.validation.Errors` and exposes validation errors as ``FieldError``s. + +[[validation-beanvalidation-spring-method-i18n]] +==== Customizing Validation Errors + The adapted `MessageSourceResolvable` errors can be turned into error messages to -display to users through the configured -xref:core/beans/context-introduction.adoc#context-functionality-messagesource[`MessageSource`] -based on locale and language specific resource bundles. +display to users through the configured `MessageSource` with locale and language specific +resource bundles. This section provides an example for illustration. -NOTE: Spring MVC and WebFlux have built-in support for method validation, and therefore -for web controller methods there is no need for a class level `@Validated` and an AOP proxy. -See the Spring MVC xref:web/webmvc/mvc-controller/ann-validation.adoc[Validation] section, -the WebFlux xref:web/webflux/controller/ann-validation.adoc[Validation] section, -and the xref:web/webmvc/mvc-controller/ann-validation.adoc[Error Responses] section. +Given the following class declarations: + +[tabs] +====== +Java:: ++ +[source,java,indent=0,subs="verbatim,quotes",role="primary"] +---- + record Person(@Size(min = 1, max = 10) String name) { + } + + @Validated + public class MyService { + + void addStudent(@Valid Person person, @Max(2) int degrees) { + // ... + } + } +---- + +Kotlin:: ++ +[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"] +---- + @JvmRecord + internal data class Person(@Size(min = 1, max = 10) val name: String) + + @Validated + class MyService { + + fun addStudent(person: @Valid Person?, degrees: @Max(2) Int) { + // ... + } + } +---- +====== + +A `ConstraintViolation` on `Person.name()` is adapted to a `FieldErrro` with the following: + +- Error codes `"Size.student.name"`, `"Size.name"`, `"Size.java.lang.String"`, and `"Size"` +- Message arguments `"name"`, `10`, and `1` (the field name and the constraint attributes) +- Default message "size must be between 1 and 10" + +To customize the default message, you can add properties to +xref:core/beans/context-introduction.adoc#context-functionality-messagesource[MessageSource] +resource bundles using any of the above errors codes and message arguments. Note also that the +message argument `"name"` is itself a `MessagreSourceResolvable` with error codes +`"student.name"` and `"name"` and can customized too. For example: +Properties:: ++ +[source,properties,indent=0,subs="verbatim,quotes",role="secondary"] +---- +Size.student.name=Please, provide a {0} that is between {2} and {1} characters long +student.name=username +---- +A `ConstraintViolation` on the `degrees` method parameter is adapted to a +`MessageSourceResolvable` with the following: + +- Error codes `"Max.myService#addStudent.degrees"`, `"Max.degrees"`, `"Max.int"`, `"Max"` +- Message arguments "degrees2 and 2 (the field name and the constraint attribute) +- Default message "must be less than or equal to 2" + +To customize the above default message, you can add a property such as: + +Properties:: ++ +[source,properties,indent=0,subs="verbatim,quotes",role="secondary"] +---- +Max.degrees=You cannot provide more than {1} {0} +---- [[validation-beanvalidation-spring-other]] diff --git a/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc b/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc index ec887afa1c0c..d8fb4a7291c2 100644 --- a/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc +++ b/framework-docs/modules/ROOT/pages/web/webflux/ann-rest-exceptions.adoc @@ -136,6 +136,14 @@ Message codes and arguments for each error are also resolved via `MessageSource` |=== +NOTE: Unlike other exceptions, the message arguments for +`WebExchangeBindException` and `HandlerMethodValidationException` are based on a list of +`MessageSourceResolvable` errors that can also be customized through a +xref:core/beans/context-introduction.adoc#context-functionality-messagesource[MessageSource] +resource bundle. See +xref:core/validation/beanvalidation.adoc#validation-beanvalidation-spring-method-i18n[Customizing Validation Errors] +for more details. + diff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc index 1f4d9ff1fd92..245e370d5200 100644 --- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc +++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc @@ -180,6 +180,13 @@ Message codes and arguments for each error are also resolved via `MessageSource` |=== +NOTE: Unlike other exceptions, the message arguments for +`MethodArgumentValidException` and `HandlerMethodValidationException` are baed on a list of +`MessageSourceResolvable` errors that can also be customized through a +xref:core/beans/context-introduction.adoc#context-functionality-messagesource[MessageSource] +resource bundle. See +xref:core/validation/beanvalidation.adoc#validation-beanvalidation-spring-method-i18n[Customizing Validation Errors] +for more details.