|
|
|
@ -5,14 +5,14 @@ There are pros and cons for considering validation as business logic, and Spring |
|
|
|
a design for validation (and data binding) that does not exclude either one of them. |
|
|
|
a design for validation (and data binding) that does not exclude either one of them. |
|
|
|
Specifically, validation should not be tied to the web tier and should be easy to localize, |
|
|
|
Specifically, validation should not be tied to the web tier and should be easy to localize, |
|
|
|
and it should be possible to plug in any available validator. Considering these concerns, |
|
|
|
and it should be possible to plug in any available validator. Considering these concerns, |
|
|
|
Spring has come up with a `Validator` interface that is both basic and eminently usable |
|
|
|
Spring provides a `Validator` contract that is both basic and eminently usable |
|
|
|
in every layer of an application. |
|
|
|
in every layer of an application. |
|
|
|
|
|
|
|
|
|
|
|
Data binding is useful for letting user input be dynamically bound to the domain |
|
|
|
Data binding is useful for letting user input be dynamically bound to the domain |
|
|
|
model of an application (or whatever objects you use to process user input). Spring |
|
|
|
model of an application (or whatever objects you use to process user input). Spring |
|
|
|
provides the aptly named `DataBinder` to do exactly that. The `Validator` and the |
|
|
|
provides the aptly named `DataBinder` to do exactly that. The `Validator` and the |
|
|
|
`DataBinder` make up the `validation` package, which is primarily used in but not |
|
|
|
`DataBinder` make up the `validation` package, which is primarily used in but not |
|
|
|
limited to the MVC framework. |
|
|
|
limited to the web layer. |
|
|
|
|
|
|
|
|
|
|
|
The `BeanWrapper` is a fundamental concept in the Spring Framework and is used in a lot |
|
|
|
The `BeanWrapper` is a fundamental concept in the Spring Framework and is used in a lot |
|
|
|
of places. However, you probably do not need to use the `BeanWrapper` |
|
|
|
of places. However, you probably do not need to use the `BeanWrapper` |
|
|
|
@ -28,19 +28,12 @@ general type conversion facility, as well as a higher-level "`format`" package f |
|
|
|
formatting UI field values. You can use these packages as simpler alternatives to |
|
|
|
formatting UI field values. You can use these packages as simpler alternatives to |
|
|
|
`PropertyEditorSupport` implementations. They are also discussed in this chapter. |
|
|
|
`PropertyEditorSupport` implementations. They are also discussed in this chapter. |
|
|
|
|
|
|
|
|
|
|
|
.JSR-303/JSR-349 Bean Validation |
|
|
|
Spring supports Java Bean Validation through setup infrastructure and an adaptor to |
|
|
|
**** |
|
|
|
Spring's own `Validator` contract. Application can enable Bean Validation once globally, |
|
|
|
As of version 4.0, Spring Framework supports Bean Validation 1.0 (JSR-303) and |
|
|
|
as described in <<validation-beanvalidation>>, and use it exclusively for all validation |
|
|
|
Bean Validation 1.1 (JSR-349) for setup support and adapting them to Spring's |
|
|
|
needs. In the web layer, they can further register controller-local local Spring |
|
|
|
`Validator` interface. |
|
|
|
`Validator` instances per `DataBinder`, as described in <<validation-binder>>, which can |
|
|
|
|
|
|
|
be useful for plugging in custom validation logic creating annotations. |
|
|
|
An application can choose to enable Bean Validation once globally, as described in |
|
|
|
|
|
|
|
<<validation-beanvalidation>>, and use it exclusively for all validation needs. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
An application can also register additional Spring `Validator` instances for each |
|
|
|
|
|
|
|
`DataBinder` instance, as described in <<validation-binder>>. This may be useful for |
|
|
|
|
|
|
|
plugging in validation logic without the use of annotations. |
|
|
|
|
|
|
|
**** |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -1811,22 +1804,20 @@ See <<web.adoc#mvc-config-conversion, Conversion and Formatting>> for details. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[validation-beanvalidation]] |
|
|
|
[[validation-beanvalidation]] |
|
|
|
== Spring Validation |
|
|
|
== Java Bean Validation |
|
|
|
|
|
|
|
|
|
|
|
Spring 3 introduced several enhancements to its validation support. First, the JSR-303 |
|
|
|
The Spring Framework provides support for the |
|
|
|
Bean Validation API is fully supported. Second, when used programmatically, Spring's |
|
|
|
https://beanvalidation.org/[Java Bean Validation] API. |
|
|
|
`DataBinder` can validate objects as well as bind to them. Third, Spring MVC has |
|
|
|
|
|
|
|
support for declaratively validating `@Controller` inputs. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[validation-beanvalidation-overview]] |
|
|
|
[[validation-beanvalidation-overview]] |
|
|
|
=== Overview of the JSR-303 Bean Validation API |
|
|
|
=== Overview of Bean Validation |
|
|
|
|
|
|
|
|
|
|
|
JSR-303 standardizes validation constraint declaration and metadata for the Java |
|
|
|
Bean Validation provides a common way of validation through constraint declaration and |
|
|
|
platform. By using this API, you annotate domain model properties with declarative |
|
|
|
metadata for Java applications. To use it, you annotate domain model properties with |
|
|
|
validation constraints and the runtime enforces them. You can use a number of built-in |
|
|
|
declarative validation constraints which are then enforced by the runtime. There are |
|
|
|
constraints. You can also define your own custom constraints. |
|
|
|
built-in constraints, and you can also define your own custom constraints. |
|
|
|
|
|
|
|
|
|
|
|
Consider the following example, which shows a simple `PersonForm` model with two properties: |
|
|
|
Consider the following example, which shows a simple `PersonForm` model with two properties: |
|
|
|
|
|
|
|
|
|
|
|
@ -1847,8 +1838,7 @@ Consider the following example, which shows a simple `PersonForm` model with two |
|
|
|
) |
|
|
|
) |
|
|
|
---- |
|
|
|
---- |
|
|
|
|
|
|
|
|
|
|
|
JSR-303 lets you define declarative validation constraints against such properties, as the |
|
|
|
Bean Validation lets you declare constraints as the following example shows: |
|
|
|
following example shows: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes",role="primary"] |
|
|
|
[source,java,indent=0,subs="verbatim,quotes",role="primary"] |
|
|
|
.Java |
|
|
|
.Java |
|
|
|
@ -1874,13 +1864,10 @@ following example shows: |
|
|
|
) |
|
|
|
) |
|
|
|
---- |
|
|
|
---- |
|
|
|
|
|
|
|
|
|
|
|
When a JSR-303 Validator validates an instance of this class, these constraints |
|
|
|
A Bean Validation validator then validates instances of this class based on the declared |
|
|
|
are enforced. |
|
|
|
constraints. See https://beanvalidation.org/[Bean Validation] for general information about |
|
|
|
|
|
|
|
the API. See the https://hibernate.org/validator/[Hibernate Validator] documentation for |
|
|
|
For general information on JSR-303 and JSR-349, see the https://beanvalidation.org/[Bean |
|
|
|
specific constraints. To learn how to set up a bean validation provider as a Spring |
|
|
|
Validation website]. For information on the specific capabilities of the default |
|
|
|
|
|
|
|
reference implementation, see the https://www.hibernate.org/412.html[Hibernate |
|
|
|
|
|
|
|
Validator] documentation. To learn how to set up a bean validation provider as a Spring |
|
|
|
|
|
|
|
bean, keep reading. |
|
|
|
bean, keep reading. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -1888,32 +1875,48 @@ bean, keep reading. |
|
|
|
[[validation-beanvalidation-spring]] |
|
|
|
[[validation-beanvalidation-spring]] |
|
|
|
=== Configuring a Bean Validation Provider |
|
|
|
=== Configuring a Bean Validation Provider |
|
|
|
|
|
|
|
|
|
|
|
Spring provides full support for the Bean Validation API. This includes convenient |
|
|
|
Spring provides full support for the Bean Validation API including the bootstrapping of a |
|
|
|
support for bootstrapping a JSR-303 or JSR-349 Bean Validation provider as a Spring bean. |
|
|
|
Bean Validation provider as a Spring bean. This lets you inject a |
|
|
|
This lets you inject a `javax.validation.ValidatorFactory` or `javax.validation.Validator` |
|
|
|
`javax.validation.ValidatorFactory` or `javax.validation.Validator` wherever validation is |
|
|
|
wherever validation is needed in your application. |
|
|
|
needed in your application. |
|
|
|
|
|
|
|
|
|
|
|
You can use the `LocalValidatorFactoryBean` to configure a default Validator as a Spring bean, |
|
|
|
You can use the `LocalValidatorFactoryBean` to configure a default Validator as a Spring |
|
|
|
as the following example shows: |
|
|
|
bean, as the following example shows: |
|
|
|
|
|
|
|
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes"] |
|
|
|
[source,java,indent=0,subs="verbatim,quotes",role="primary"] |
|
|
|
|
|
|
|
.Java |
|
|
|
|
|
|
|
---- |
|
|
|
|
|
|
|
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Configuration |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class AppConfig { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Bean |
|
|
|
|
|
|
|
public LocalValidatorFactoryBean validator() { |
|
|
|
|
|
|
|
return new LocalValidatorFactoryBean; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
---- |
|
|
|
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes",role="secondary"] |
|
|
|
|
|
|
|
.XML |
|
|
|
---- |
|
|
|
---- |
|
|
|
<bean id="validator" |
|
|
|
<bean id="validator" |
|
|
|
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/> |
|
|
|
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/> |
|
|
|
---- |
|
|
|
---- |
|
|
|
|
|
|
|
|
|
|
|
The basic configuration in the preceding example triggers bean validation to initialize by using its |
|
|
|
The basic configuration in the preceding example triggers bean validation to initialize by |
|
|
|
default bootstrap mechanism. A JSR-303 or JSR-349 provider, such as the Hibernate Validator, |
|
|
|
using its default bootstrap mechanism. A Bean Validation provider, such as the Hibernate |
|
|
|
is expected to be present in the classpath and is automatically detected. |
|
|
|
Validator, is expected to be present in the classpath and is automatically detected. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[validation-beanvalidation-spring-inject]] |
|
|
|
[[validation-beanvalidation-spring-inject]] |
|
|
|
==== Injecting a Validator |
|
|
|
==== Injecting a Validator |
|
|
|
|
|
|
|
|
|
|
|
`LocalValidatorFactoryBean` implements both `javax.validation.ValidatorFactory` and |
|
|
|
`LocalValidatorFactoryBean` implements both `javax.validation.ValidatorFactory` and |
|
|
|
`javax.validation.Validator`, as well as Spring's |
|
|
|
`javax.validation.Validator`, as well as Spring's `org.springframework.validation.Validator`. |
|
|
|
`org.springframework.validation.Validator`. You can inject a reference to either of |
|
|
|
You can inject a reference to either of these interfaces into beans that need to invoke |
|
|
|
these interfaces into beans that need to invoke validation logic. |
|
|
|
validation logic. |
|
|
|
|
|
|
|
|
|
|
|
You can inject a reference to `javax.validation.Validator` if you prefer to work with the Bean |
|
|
|
You can inject a reference to `javax.validation.Validator` if you prefer to work with the Bean |
|
|
|
Validation API directly, as the following example shows: |
|
|
|
Validation API directly, as the following example shows: |
|
|
|
@ -1939,8 +1942,8 @@ Validation API directly, as the following example shows: |
|
|
|
class MyService(@Autowired private val validator: Validator) |
|
|
|
class MyService(@Autowired private val validator: Validator) |
|
|
|
---- |
|
|
|
---- |
|
|
|
|
|
|
|
|
|
|
|
You can inject a reference to `org.springframework.validation.Validator` if your bean requires |
|
|
|
You can inject a reference to `org.springframework.validation.Validator` if your bean |
|
|
|
the Spring Validation API, as the following example shows: |
|
|
|
requires the Spring Validation API, as the following example shows: |
|
|
|
|
|
|
|
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes",role="primary"] |
|
|
|
[source,java,indent=0,subs="verbatim,quotes",role="primary"] |
|
|
|
.Java |
|
|
|
.Java |
|
|
|
@ -1968,11 +1971,9 @@ the Spring Validation API, as the following example shows: |
|
|
|
==== Configuring Custom Constraints |
|
|
|
==== Configuring Custom Constraints |
|
|
|
|
|
|
|
|
|
|
|
Each bean validation constraint consists of two parts: |
|
|
|
Each bean validation constraint consists of two parts: |
|
|
|
* A `@Constraint` annotation |
|
|
|
* A `@Constraint` annotation that declares the constraint and its configurable properties. |
|
|
|
that declares the constraint and its configurable properties. |
|
|
|
* An implementation of the `javax.validation.ConstraintValidator` interface that implements |
|
|
|
* An implementation |
|
|
|
the constraint's behavior. |
|
|
|
of the `javax.validation.ConstraintValidator` interface that implements the constraint's |
|
|
|
|
|
|
|
behavior. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
To associate a declaration with an implementation, each `@Constraint` annotation |
|
|
|
To associate a declaration with an implementation, each `@Constraint` annotation |
|
|
|
references a corresponding `ConstraintValidator` implementation class. At runtime, a |
|
|
|
references a corresponding `ConstraintValidator` implementation class. At runtime, a |
|
|
|
@ -2036,19 +2037,48 @@ As the preceding example shows, a `ConstraintValidator` implementation can have |
|
|
|
[[validation-beanvalidation-spring-method]] |
|
|
|
[[validation-beanvalidation-spring-method]] |
|
|
|
==== Spring-driven Method Validation |
|
|
|
==== Spring-driven Method Validation |
|
|
|
|
|
|
|
|
|
|
|
You can integrate the method validation feature supported by Bean Validation 1.1 (and, as a custom |
|
|
|
You can integrate the method validation feature supported by Bean Validation 1.1 (and, as |
|
|
|
extension, also by Hibernate Validator 4.3) into a Spring context |
|
|
|
a custom extension, also by Hibernate Validator 4.3) into a Spring context through a |
|
|
|
through a `MethodValidationPostProcessor` bean definition, as follows: |
|
|
|
`MethodValidationPostProcessor` bean definition: |
|
|
|
|
|
|
|
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes"] |
|
|
|
[source,java,indent=0,subs="verbatim,quotes",role="primary"] |
|
|
|
|
|
|
|
.Java |
|
|
|
|
|
|
|
---- |
|
|
|
|
|
|
|
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Configuration |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class AppConfig { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Bean |
|
|
|
|
|
|
|
public MethodValidationPostProcessor validationPostProcessor() { |
|
|
|
|
|
|
|
return new MethodValidationPostProcessor; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---- |
|
|
|
|
|
|
|
[source,xml,indent=0,subs="verbatim,quotes",role="secondary"] |
|
|
|
|
|
|
|
.XML |
|
|
|
---- |
|
|
|
---- |
|
|
|
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/> |
|
|
|
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/> |
|
|
|
---- |
|
|
|
---- |
|
|
|
|
|
|
|
|
|
|
|
To be eligible for Spring-driven method validation, all target classes need to be annotated with |
|
|
|
To be eligible for Spring-driven method validation, all target classes need to be annotated |
|
|
|
Spring's `@Validated` annotation. (Optionally, you can also declare the validation groups to use.) |
|
|
|
with Spring's `@Validated` annotation, which can optionally also declare the validation |
|
|
|
See the {api-spring-framework}/validation/beanvalidation/MethodValidationPostProcessor.html[`MethodValidationPostProcessor`] |
|
|
|
groups to use. See |
|
|
|
javadoc for setup details with the Hibernate Validator and Bean Validation 1.1 providers. |
|
|
|
{api-spring-framework}/validation/beanvalidation/MethodValidationPostProcessor.html[`MethodValidationPostProcessor`] |
|
|
|
|
|
|
|
for setup details with the Hibernate Validator and Bean Validation 1.1 providers. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[TIP] |
|
|
|
|
|
|
|
==== |
|
|
|
|
|
|
|
Method validation relies on <<core.adoc#aop-introduction-proxies,AOP Proxies>> around the |
|
|
|
|
|
|
|
target classes, either JDK dynamic proxies for methods on interfaces or CGLIB proxies. |
|
|
|
|
|
|
|
There are certain limitations with the use of proxies, some of which are described in |
|
|
|
|
|
|
|
<<core.adoc#aop-understanding-aop-proxies,Understanding AOP Proxies>>. In addition remember |
|
|
|
|
|
|
|
to always use methods and accessors on proxied classes; direct field access will not work. |
|
|
|
|
|
|
|
==== |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[validation-beanvalidation-spring-other]] |
|
|
|
[[validation-beanvalidation-spring-other]] |
|
|
|
@ -2108,7 +2138,8 @@ logic after binding to a target object: |
|
|
|
You can also configure a `DataBinder` with multiple `Validator` instances through |
|
|
|
You can also configure a `DataBinder` with multiple `Validator` instances through |
|
|
|
`dataBinder.addValidators` and `dataBinder.replaceValidators`. This is useful when |
|
|
|
`dataBinder.addValidators` and `dataBinder.replaceValidators`. This is useful when |
|
|
|
combining globally configured bean validation with a Spring `Validator` configured |
|
|
|
combining globally configured bean validation with a Spring `Validator` configured |
|
|
|
locally on a DataBinder instance. See <<validation-mvc-configuring>>. |
|
|
|
locally on a DataBinder instance. See |
|
|
|
|
|
|
|
<<web.adoc#mvc-config-validation,Spring MVC Validation Configuration>>. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|