This commit is contained in:
Keith Donald 2009-09-14 21:32:13 +00:00
parent d5ed42e860
commit 90697e884d
1 changed files with 169 additions and 169 deletions

View File

@ -1207,35 +1207,36 @@ public interface FormatterRegistry {
This applies the Formatter to the field, and overrides any Formatter that would have been applied by field type or annotation. This applies the Formatter to the field, and overrides any Formatter that would have been applied by field type or annotation.
</para> </para>
</section> </section>
<section id="validation.beanvalidation"> </section>
<title>Spring 3 Validation</title> <section id="validation.beanvalidation">
<title>Spring 3 Validation</title>
<para>
Spring 3 introduces several enhancements to its validation support.
First, the JSR-303 Bean Validation API is now fully supported.
Second, when used programatically, Spring's DataBinder can now validate objects as well as bind to them.
Third, Spring MVC now has support for declaratively validating @Controller inputs.
</para>
<section id="validation.beanvalidation.overview">
<title>Overview of the Bean Validation API (JSR-303)</title>
<para> <para>
Spring 3 introduces several enhancements to its validation support. The Bean Validation API (JSR-303) standardizes validation constraint declaration and metadata for the Java platform.
First, the JSR-303 Bean Validation API is now fully supported. Using this API, you annotate domain model properties with declarative validation constraints and the runtime enforces them.
Second, when used programatically, Spring's DataBinder can now validate objects as well as bind to them. There are a number of built-in constraints you can can take advantage of.
Third, Spring MVC now has support for declaratively validating @Controller inputs. You may also define your own custom constraints.
</para> </para>
<secton id="validation.beanvalidation.overview"> <para>
<title>Overview of the Bean Validation API (JSR-303)</title> To illustrate, consider a simple Person model with two properties:
<para> </para>
The Bean Validation API (JSR-303) standardizes validation constraint declaration and metadata for the Java platform. <programlisting language="java"><![CDATA[
Using this API, you annotate domain model properties with declarative validation constraints and the runtime enforces them.
There are a number of built-in constraints you can can take advantage of.
You may also define your own custom constraints.
</para>
<para>
To illustrate, consider a simple Person model with two properties:
</para>
<programlisting language="java"><![CDATA[
public class Person { public class Person {
private String name; private String name;
private int age; private int age;
}]]> }]]>
</programlisting> </programlisting>
<para> <para>
JSR-303 allows you to define declarative validation constraints against such properties: JSR-303 allows you to define declarative validation constraints against such properties:
</para> </para>
<programlisting language="java"><![CDATA[ <programlisting language="java"><![CDATA[
public class Person { public class Person {
@NotNull @NotNull
@ -1244,45 +1245,45 @@ public class Person {
@Min(0) @Min(0)
private int age; private int age;
}]]> }]]>
</programlisting> </programlisting>
<para>
When this object is processed by a JSR-303 Validator, these constraints will be validated.
</para>
<para>
For general information on JSR-303, see the <ulink url="http://jcp.org/en/jsr/detail?id=303">Bean Validation Specification</ulink>.
For information on the specific capabilities of the default reference implementation, see the <ulink url="https://www.hibernate.org/412.html">Hibernate Validator</ulink> documentation.
For how to setup a JSR-303 implementation as a Spring bean, keep reading.
</para>
</section>
<section id="validation.beanvalidation.spring">
<title>Configuring a Bean Validation Implementation</title>
<para>
Spring provides full support for the JSR-303 Bean Validation API.
This includes convenient support for bootstrapping a JSR-303 implementation as a Spring bean.
This allows a <code>javax.validation.Validator</code> to be injected wherever validation is needed.
</para>
<para>
Use the LocalValidatorFactoryBean to configure a default JSR-303 Validator as a Spring bean:
</para>
<programlisting language="xml"><![CDATA[
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />]]>
</programlisting>
<para>
The basic configuration above will trigger JSR-303 to initialize using its default bootstrap mechanism.
The JSR-303 provider, such as Hibernate Validator, will be detected in your classpath automatically.
</para>
<section id="validation.beanvalidation.spring.inject">
<title>Injecting a Validator</title>
<para> <para>
When this object is processed by a JSR-303 Validator, these constraints will be validated. LocalValidatorFactoryBean implements <code>javax.validation.Validator</code> as well as <code>org.springframework.validation.Validator</code>.
Once created, you may inject a reference to either of these interfaces to other beans that need to invoke JSR-303 validation logic.
</para> </para>
<para> <para>
For general information on JSR-303, see the <ulink url="http://jcp.org/en/jsr/detail?id=303">Bean Validation Specification</ulink>. Inject a reference to <code>javax.validation.Validator</code> if you prefer to work with the JSR-303 API directly:
For information on the specific capabilities of the default reference implementation, see the <ulink url="https://www.hibernate.org/412.html">Hibernate Validator</ulink> documentation.
For how to setup a JSR-303 implementation as a Spring bean, keep reading.
</para> </para>
</section> <programlisting language="java"><![CDATA[
<secton id="validation.beanvalidation.spring">
<title>Configuring a Bean Validation Implementation</title>
<para>
Spring provides full support for the JSR-303 Bean Validation API.
This includes convenient support for bootstrapping a JSR-303 implementation as a Spring bean.
This allows a <code>javax.validation.Validator</code> to be injected wherever validation is needed.
</para>
<para>
Use the LocalValidatorFactoryBean to configure a default JSR-303 Validator as a Spring bean:
</para>
<programlisting language="xml"><![CDATA[
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
}]]>
</programlisting>
<para>
The basic configuration above will trigger JSR-303 to initialize using its default bootstrap mechanism.
The JSR-303 provider, such as Hibernate Validator, will be detected in your classpath automatically.
</para>
<section id="validation.beanvalidation.spring.inject">
<title>Injecting a Validator</title>
<para>
LocalValidatorFactoryBean implements <code>javax.validation.Validator</code> as well as <code>org.springframework.validation.Validator</code>.
Once created, you may inject a reference to either of these interfaces to other beans that need to invoke JSR-303 validation logic.
</para>
<para>
Inject a reference to <code>javax.validation.Validator</code> if you want to work with the JSR-303 API directly:
</para>
<programlisting language="java"><![CDATA[
import javax.validation.Validator; import javax.validation.Validator;
@Service @Service
@ -1290,47 +1291,48 @@ public class MyService {
@Autowired @Autowired
private Validator validator; private Validator validator;
}]]> }]]>
</programlisting> </programlisting>
<para> <para>
Inject a reference to <code>org.springframework.validation.Validator</code> if you prefer to work with the familiar Spring Validation API: Inject a reference to <code>org.springframework.validation.Validator</code> if you prefer to work with the familiar Spring Validation API:
</para> </para>
<programlisting language="java"><![CDATA[ <programlisting language="java"><![CDATA[
import org.springframework.validation.Validator; import org.springframework.validation.Validator;
@Service @Service
public class MyService { public class MyService {
@Autowired @Autowired
private Validator validator; private Validator validator;
}]]> }]]>
</programlisting> </programlisting>
</section> </section>
<section id="validation.beanvalidation.spring.constraints"> <section id="validation.beanvalidation.spring.constraints">
<title>Configuring Custom Constraints</title> <title>Configuring Custom Constraints</title>
<para> <para>
Each JSR-303 validation constraint consists of two parts. Each JSR-303 validation constraint consists of two parts.
First, a @Constraint annotation that declares the constraint and its configurable properties. First, a @Constraint annotation that declares the constraint and its configurable properties.
Second, an implementation of the <code>javax.validation.ConstraintValidator</code> interface that implements the constraint's behavior. Second, an implementation of the <code>javax.validation.ConstraintValidator</code> interface that implements the constraint's behavior.
To associate a declaration with an implementation, each @Constraint annotation references its corresponding ValidationConstraint implementation class. To associate a declaration with an implementation, each @Constraint annotation references its corresponding ValidationConstraint implementation class.
At runtime, the <code>ConstraintValidatorFactory</code> then creates instances of this class when the constraint annotation is encountered in your domain model. At runtime, the <code>ConstraintValidatorFactory</code> then creates instances of this class when the constraint annotation is encountered in your domain model.
</para> </para>
<para> <para>
The <code>LocalValidatorFactoryBean</code> automatically configures a <code>SpringConstraintValidatorFactory</code> that uses Spring to create ConstraintValidator instances. The <code>LocalValidatorFactoryBean</code> automatically configures a <code>SpringConstraintValidatorFactory</code> that uses Spring to create ConstraintValidator instances.
This allows your custom ConstraintValidators to benefit from dependency injection like any other Spring bean. This allows your custom ConstraintValidators to benefit from dependency injection like any other Spring bean.
</para> </para>
<para> <para>
Below is an example of a custom constraint declaration and implementation that uses Spring dependency injection: Below is an example of a custom constraint declaration and implementation that uses Spring dependency injection:
</para> </para>
<programlisting language="java"><![CDATA[ <programlisting language="java"><![CDATA[
@Target({ElementType.METHOD, ElementType.FIELD}) @Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy=MyConstraintValidator.class) @Constraint(validatedBy=MyConstraintValidator.class)
public @interface MyConstraint { public @interface MyConstraint {
} }]]>
]]> </programlisting>
</programlisting> <programlisting language="java"><![CDATA[
<programlisting language="java"><![CDATA[
import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidator;
public class MyConstraintValidator implements ConstraintValidator { public class MyConstraintValidator implements ConstraintValidator {
@ -1339,28 +1341,28 @@ public class MyConstraintValidator implements ConstraintValidator {
private Foo aDependency; private Foo aDependency;
}]]> }]]>
</programlisting> </programlisting>
</section>
<section id="validation.beanvalidation.spring.other">
<title>Additional Configuration Options</title>
<para>
The default <code>LocalValidatorFactoryBean</code> configuration should prove sufficient for most cases.
There are a number of other explicit configuration options for various JSR-303 constructs, from message interpolation to traversal resolution.
See the JavaDocs of LocalValidatorFactoryBean more information on these options.
</para>
</section>
</section> </section>
<secton id="validation.binder"> <section id="validation.beanvalidation.spring.other">
<title>Configuring a DataBinder</title> <title>Additional Configuration Options</title>
<para> <para>
Since Spring 3, a DataBinder instance can now be configured with a Validator. The default <code>LocalValidatorFactoryBean</code> configuration should prove sufficient for most cases.
Once configured, the Validator may be subsequently invoked by calling <code>binder.validate()</code>. There are a number of other explicit configuration options for various JSR-303 constructs, from message interpolation to traversal resolution.
Any ValidationErrors are automatically added to the binder's BindingResults. See the JavaDocs of LocalValidatorFactoryBean more information on these options.
</para> </para>
<para> </section>
When working with the DataBinder programatically, this can be used to invoke validation logic after binding to a target object: </section>
</para> <section id="validation.binder">
<programlisting language="java"><![CDATA[ <title>Configuring a DataBinder</title>
<para>
Since Spring 3, a DataBinder instance can now be configured with a Validator.
Once configured, the Validator may be subsequently invoked by calling <code>binder.validate()</code>.
Any validation Errors are automatically added to the binder's BindingResults.
</para>
<para>
When working with the DataBinder programatically, this feature can be used to invoke validation logic after binding to a target object:
</para>
<programlisting language="java"><![CDATA[
DataBinder binder = new DataBinder(new Foo()); DataBinder binder = new DataBinder(new Foo());
binder.setValidator(new FooValidator()); binder.setValidator(new FooValidator());
@ -1371,46 +1373,46 @@ binder.bind(propertyValues);
binder.validate(); binder.validate();
// get BindingResults that include any validation errors // get BindingResults that include any validation errors
BindingResults results = binder.getBindingResults(); BindingResults results = binder.getBindingResults();}]]>
}]]> </programlisting>
</programlisting> </section>
</section> <section id="validation.mvc">
<secton id="validation.mvc"> <title>Spring MVC 3 Validation</title>
<title>Spring MVC 3 Validation</title> <para>
Spring MVC 3 now has the ability to automatically validate @Controller method arguments after binding.
Before version 3, it was up to the developer to manually invoke object Validation logic.
</para>
<section id="validation.mvc.triggering">
<title>Triggering @Controller Method Argument Validation</title>
<para> <para>
Spring MVC 3 now has the ability to automatically validate @Controller method arguments after binding. To trigger validation of a @Controller method argument, simply annotate the argument as @Valid:
Before version 3, it was up to the developer to manually invoke object Validation logic.
</para> </para>
<section id="validation.mvc.triggering"> <programlisting language="java"><![CDATA[
<title>Triggering @Controller Method Argument Validation</title>
<para>
To trigger validation of a @Controller method argument, simply annotate the argument as @Valid:
</para>
<programlisting language="java"><![CDATA[
@Controller @Controller
public class MyController { public class MyController {
@RequestMapping("/foo", method=RequestMethod.POST) @RequestMapping("/foo", method=RequestMethod.POST)
public void processFoo(@Valid Foo foo) { ... } public void processFoo(@Valid Foo foo) { ... }
}]]> }]]>
</programlisting> </programlisting>
<para>
Spring MVC will validate a @Valid object after binding so-long as an appropriate Validator has been configured.
</para>
<note>
<para> <para>
Spring MVC will validate a @Valid object after binding so-long as an appropriate Validator has been configured. The @Valid annotation is part of the standard JSR-303 Bean Validation API, and not a Spring-specific construct.
</para> </para>
<note> </note>
<para> </section>
The @Valid annotation is part of the standard JSR-303 Bean Validation API, and not a Spring-specific construct. <section id="validation.mvc.configuring">
</para> <title>Configuring a Validator for use by Spring MVC</title>
</note> <para>
</section> The Validator instance invoked when a @Valid method argument is encountered may be configured in two ways.
<section id="validation.mvc.configuring"> First, you may call binder.setValidator(Validator) within a @Controller's @InitBinder callback method.
<title>Configuring a Validator for use by Spring MVC</title> This allows you to configure a Validator instance per @Controller class:
<para> </para>
The Validator instance invoked when a @Valid method argument is encountered may be configured in two ways. <programlisting language="java"><![CDATA[
First, you may call binder.setValidator(Validator) within a @Controller's @InitBinder callback method.
This allows you to configure a Validator instance per @Controller class:
</para>
<programlisting language="java"><![CDATA[
@Controller @Controller
public class MyController { public class MyController {
@ -1420,16 +1422,15 @@ public class MyController {
} }
@RequestMapping("/foo", method=RequestMethod.POST) @RequestMapping("/foo", method=RequestMethod.POST)
public void processFoo(@Valid Foo foo) { ... } public void processFoo(@Valid Foo foo) { ... }
}
]]> }]]>
</programlisting> </programlisting>
<para> <para>
Second, you may call setValidator(Validator) on the global WebBindingInitializer. Second, you may call setValidator(Validator) on the global WebBindingInitializer.
This allows you to configure a Validator instance across all @Controllers: This allows you to configure a Validator instance across all @Controllers:
</para> </para>
<programlisting language="xml"><![CDATA[ <programlisting language="xml"><![CDATA[
<!-- Invokes Spring MVC @Controller methods --> <!-- Invokes Spring MVC @Controller methods -->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="webBindingInitializer"> <property name="webBindingInitializer">
@ -1439,20 +1440,20 @@ public class MyController {
</bean> </bean>
</property> </property>
</bean>]]> </bean>]]>
</programlisting> </programlisting>
</section> </section>
<section id="validation.mvc.jsr303"> <section id="validation.mvc.jsr303">
<title>Configuring a JSR-303 Validator for use by Spring MVC</title> <title>Configuring a JSR-303 Validator for use by Spring MVC</title>
<para> <para>
With JSR-303, the default <code>javax.validation.Validator</code> implementation is quite generic. With JSR-303, the default <code>javax.validation.Validator</code> implementation is quite generic.
A single instance typically coordinates the validation of <emphasis>all</emphasis> application objects that declare validation constraints. A single instance typically coordinates the validation of <emphasis>all</emphasis> application objects that declare validation constraints.
To configure such a Validator for use by Spring MVC, simply inject a <code>LocalValidatorFactoryBean</code> reference into the <code>WebBindingInitializer</code> as shown in the previous section. To configure such a Validator for use by Spring MVC, simply inject a <code>LocalValidatorFactoryBean</code> reference into the <code>WebBindingInitializer</code> as shown in the previous section.
<code>LocalValidatorFactoryBean</code> already implements <code>org.springframework.validation.Validation</code>, delegating to the JSR-303 provider underneath. <code>LocalValidatorFactoryBean</code> already implements <code>org.springframework.validation.Validation</code>, delegating to the JSR-303 provider underneath.
</para> </para>
<para> <para>
A full configuration example showing injection of a JSR-303 backed Validator into Spring MVC is shown below: A full configuration example showing injection of a JSR-303 backed Validator into Spring MVC is shown below:
</para> </para>
<programlisting language="xml"><![CDATA[ <programlisting language="xml"><![CDATA[
<!-- Invokes Spring MVC @Controller methods --> <!-- Invokes Spring MVC @Controller methods -->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="webBindingInitializer"> <property name="webBindingInitializer">
@ -1460,16 +1461,15 @@ public class MyController {
<bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer"> <bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
<property name="validator" ref="validator" /> <property name="validator" ref="validator" />
</bean> </bean>
</property> </property>
</bean> </bean>
<!-- Creates the JSR-303 Validator --> <!-- Creates the JSR-303 Validator -->
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />]]> <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />]]>
</programlisting> </programlisting>
<para> <para>
With this configuration, anytime a @Valid @Controller method argument is encountered, it will be validated using JSR-303. With this configuration, anytime a @Valid @Controller method argument is encountered, it will be validated using JSR-303.
</para> </para>
</section>
</section> </section>
</section> </section>
</section> </section>