diff --git a/src/reference/docbook/validation.xml b/src/reference/docbook/validation.xml index 2eb98a76b02..075f0ed9cab 100644 --- a/src/reference/docbook/validation.xml +++ b/src/reference/docbook/validation.xml @@ -13,12 +13,13 @@ Introduction - JSR-303 Bean Validation + JSR-303/JSR-349 Bean Validation - The Spring Framework supports JSR-303 Bean Validation adapting + Spring Framework 4.0 supports Bean Validation 1.0 (JSR-303) and + Bean Validation 1.1 (JSR-349) in terms of setup support, also adapting it to Spring's Validator interface. - An application can choose to enable JSR-303 Bean Validation once globally, + An application can choose to enable Bean Validation once globally, as described in , and use it exclusively for all validation needs. @@ -36,7 +37,7 @@ the web tier, should be easy to localize and it should be possible to plug in any validator available. Considering the above, Spring has come up with a Validator interface that is both basic - ands eminently usable in every layer of an application. + ands eminently usable in every layer of an application. Data binding is useful for allowing user input to be dynamically bound to the domain model of an application (or whatever objects you use to @@ -45,7 +46,7 @@ Validator and the DataBinder make up the validation package, which is primarily used in but not - limited to the MVC framework. + limited to the MVC framework. The BeanWrapper is a fundamental concept in the Spring Framework and is used in a lot of places. However, @@ -104,9 +105,9 @@ given object and in case of validation errors, registers those with the given Errors object - + - Implementing a Validator is fairly + Implementing a Validator is fairly straightforward, especially when you know of the ValidationUtils helper class that the Spring Framework also provides. @@ -453,7 +454,7 @@ Float salary = (Float) company.getPropertyValue("managingDirector.salary");]]>PropertyEditors that you can manually bind in all subclasses of the CommandController. - + Spring has a number of built-in PropertyEditors to make life easy. Each of those is listed below and they are all @@ -600,7 +601,7 @@ Float salary = (Float) company.getPropertyValue("managingDirector.salary");]]> - Spring uses the + Spring uses the java.beans.PropertyEditorManager to set the search path for property editors that might be needed. The search path also includes sun.bean.editors, which includes @@ -615,7 +616,7 @@ Float salary = (Float) company.getPropertyValue("managingDirector.salary");]]>FooEditor class to be recognized and used as the PropertyEditor for - Foo-typed properties. + Foo-typed properties. // the BeanInfo for the Foo class - Here is the Java source code for the referenced + Here is the Java source code for the referenced FooBeanInfo class. This would associate a CustomNumberEditor with the - age property of the Foo class. + age property of the Foo class. Spring 3 Type Conversion - Spring 3 introduces a core.convert package that + Spring 3 introduces a core.convert package that provides a general type conversion system. The system defines an SPI to implement type conversion logic, as well as an API to execute type conversions at runtime. Within a Spring container, this system can be used as an alternative to PropertyEditors to convert externalized bean property value strings to required property types. The public API may also be used - anywhere in your application where type conversion is needed. + anywhere in your application where type conversion is needed.
Converter SPI - The SPI to implement type conversion logic is simple and strongly - typed: + The SPI to implement type conversion logic is simple and strongly + typed: { }]]> - To create your own Converter, simply implement the interface above. + To create your own Converter, simply implement the interface above. Parameterize S as the type you are converting from, and T as the type you are converting to. For each call to convert(S), the source argument is guaranteed to be NOT null. Your Converter may throw any Exception if conversion fails. An IllegalArgumentException should be thrown to report an invalid source value. Take care to ensure your Converter - implementation is thread-safe. + implementation is thread-safe. - Several converter implementations are provided in the + Several converter implementations are provided in the core.convert.support package as a convenience. These include converters from Strings to Numbers and other common types. Consider StringToInteger as an example Converter - implementation: + implementation: {
ConverterFactory - When you need to centralize the conversion logic for an entire + When you need to centralize the conversion logic for an entire class hierarchy, for example, when converting from String to java.lang.Enum objects, implement - ConverterFactory: + ConverterFactory: { }]]> - Parameterize S to be the type you are converting from and R to be + Parameterize S to be the type you are converting from and R to be the base type defining the range of classes you can convert to. Then implement getConverter(Class<T>), where T is a - subclass of R. + subclass of R. - Consider the StringToEnum ConverterFactory - as an example: + Consider the StringToEnum ConverterFactory + as an example: GenericConverter - When you require a sophisticated Converter implementation, consider + When you require a sophisticated Converter implementation, consider the GenericConverter interface. With a more flexible but less strongly typed signature, a GenericConverter supports converting between multiple source and target types. In addition, a GenericConverter makes available source and target field context you can use when implementing your conversion logic. Such context allows a type conversion to be driven by a field annotation, or generic information declared on a field - signature. + signature. - To implement a GenericConverter, have getConvertibleTypes() return + To implement a GenericConverter, have getConvertibleTypes() return the supported source->target type pairs. Then implement convert(Object, TypeDescriptor, TypeDescriptor) to implement your conversion logic. The source TypeDescriptor provides access to the source field holding the value being converted. The target TypeDescriptor provides access to the target field where the converted - value will be set. + value will be set. - A good example of a GenericConverter is a converter that converts + A good example of a GenericConverter is a converter that converts between a Java Array and a Collection. Such an ArrayToCollectionConverter introspects the field that declares the target Collection type to resolve the Collection's element type. This allows each element in the source array to be converted to the Collection element type before the Collection is set on the target - field. + field. - Because GenericConverter is a more complex SPI interface, only + Because GenericConverter is a more complex SPI interface, only use it when you need it. Favor Converter or ConverterFactory for basic - type conversion needs. + type conversion needs.
ConditionalGenericConverter - Sometimes you only want a Converter to execute if a specific + Sometimes you only want a Converter to execute if a specific condition holds true. For example, you might only want to execute a Converter if a specific annotation is present on the target field. Or you might only want to execute a Converter if a specific method, such as static valueOf method, is defined on the target class. ConditionalGenericConverter is an subinterface of GenericConverter - that allows you to define such custom matching criteria: + that allows you to define such custom matching criteria: - A good example of a ConditionalGenericConverter is an + A good example of a ConditionalGenericConverter is an EntityConverter that converts between an persistent entity identifier and an entity reference. Such a EntityConverter might only match if the target entity type declares a static finder method e.g. findAccount(Long). You would perform such a finder method check in the - implementation of matches(TypeDescriptor, TypeDescriptor). + implementation of matches(TypeDescriptor, TypeDescriptor).
ConversionService API - The ConversionService defines a unified API for executing type + The ConversionService defines a unified API for executing type conversion logic at runtime. Converters are often executed behind this - facade interface: + facade interface: - Most ConversionService implementations also implement + Most ConversionService implementations also implement ConverterRegistry, which provides an SPI for registering converters. Internally, a ConversionService implementation delegates to its registered converters to carry out type conversion - logic. + logic. - A robust ConversionService implementation is provided in the + A robust ConversionService implementation is provided in the core.convert.support package. GenericConversionService is the general-purpose implementation suitable for use in most environments. ConversionServiceFactory provides a convenient - factory for creating common ConversionService configurations. + factory for creating common ConversionService configurations.
Configuring a ConversionService - A ConversionService is a stateless object designed to be + A ConversionService is a stateless object designed to be instantiated at application startup, then shared between multiple threads. In a Spring application, you typically configure a ConversionService instance per Spring container (or ApplicationContext). That ConversionService will be picked up by Spring and then used whenever a type conversion needs to be performed by the framework. You may also inject this ConversionService into any of your beans and invoke - it directly. + it directly. - If no ConversionService is registered with Spring, the original - PropertyEditor-based system is used. + If no ConversionService is registered with Spring, the original + PropertyEditor-based system is used. - To register a default ConversionService with Spring, add the - following bean definition with id conversionService: + To register a default ConversionService with Spring, add the + following bean definition with id conversionService: ]]> - A default ConversionService can convert between strings, numbers, + A default ConversionService can convert between strings, numbers, enums, collections, maps, and other common types. To supplement or override the default converters with your own custom converter(s), set the converters property. Property values may implement either of the Converter, ConverterFactory, or GenericConverter - interfaces. + interfaces. @@ -1135,8 +1136,8 @@ public interface ConversionService {
Using a ConversionService programmatically - To work with a ConversionService instance programmatically, simply - inject a reference to it like you would for any other bean: + To work with a ConversionService instance programmatically, simply + inject a reference to it like you would for any other bean: Spring 3 Field Formatting - As discussed in the previous section, As discussed in the previous section, core.convert is a general-purpose type conversion system. It provides a unified ConversionService API as well as a strongly-typed Converter SPI for implementing conversion logic from one @@ -1166,9 +1167,9 @@ public class MyService { needs to coerce a Short to a Long to complete an expression.setValue(Object bean, Object value) - attempt, the core.convert system performs the coercion. + attempt, the core.convert system performs the coercion. - Now consider the type conversion requirements of a typical client + Now consider the type conversion requirements of a typical client environment such as a web or desktop application. In such environments, you typically convert from String to support the client postback process, as well as back to String to @@ -1177,28 +1178,28 @@ public class MyService { Converter SPI does not address such formatting requirements directly. To directly address them, Spring 3 introduces a convenient Formatter SPI that provides a simple and robust alternative to - PropertyEditors for client environments. + PropertyEditors for client environments. - In general, use the Converter SPI when you need to implement + In general, use the Converter SPI when you need to implement general-purpose type conversion logic; for example, for converting between a java.util.Date and and java.lang.Long. Use the Formatter SPI when you're working in a client environment, such as a web application, and need to parse and print localized field values. The ConversionService provides a - unified type conversion API for both SPIs. + unified type conversion API for both SPIs.
Formatter SPI - The Formatter SPI to implement field formatting logic is simple and - strongly typed: + The Formatter SPI to implement field formatting logic is simple and + strongly typed: extends Printer, Parser { }]]> - Where Formatter extends from the Printer and Parser building-block - interfaces: + Where Formatter extends from the Printer and Parser building-block + interfaces: { String print(T fieldValue, Locale locale); @@ -1210,7 +1211,7 @@ public interface Parser { T parse(String clientValue, Locale locale) throws ParseException; }]]> - To create your own Formatter, simply implement the Formatter + To create your own Formatter, simply implement the Formatter interface above. Parameterize T to be the type of object you wish to format, for example, java.util.Date. Implement the print() operation to print an instance of T @@ -1219,9 +1220,9 @@ public interface Parser { the formatted representation returned from the client locale. Your Formatter should throw a ParseException or IllegalArgumentException if a parse attempt fails. Take care to ensure your Formatter implementation - is thread-safe. + is thread-safe. - Several Formatter implementations are provided in + Several Formatter implementations are provided in format subpackages as a convenience. The number package provides a NumberFormatter, CurrencyFormatter, and PercentFormatter to format java.lang.Number @@ -1230,10 +1231,10 @@ public interface Parser { java.util.Date objects with a java.text.DateFormat. The datetime.joda package provides comprehensive datetime formatting support based on the Joda Time library. + xl:href="http://joda-time.sourceforge.net">Joda Time library. - Consider DateFormatter as an example - Formatter implementation: + Consider DateFormatter as an example + Formatter implementation: { }]]> - The Spring team welcomes community-driven Formatter contributions; + The Spring team welcomes community-driven Formatter contributions; see http://jira.springframework.org to contribute. + >http://jira.springframework.org to contribute.
Annotation-driven Formatting - As you will see, field formatting can be configured by field type + As you will see, field formatting can be configured by field type or annotation. To bind an Annotation to a formatter, implement - AnnotationFormatterFactory: + AnnotationFormatterFactory: { }]]> - Parameterize A to be the field annotationType you wish to associate + Parameterize A to be the field annotationType you wish to associate formatting logic with, for example org.springframework.format.annotation.DateTimeFormat. Have getFieldTypes() return the types of fields the annotation may be used on. Have getPrinter() return a Printer to print the value of an annotated field. Have getParser() return a Parser to parse a - clientValue for an annotated field. + clientValue for an annotated field. - The example AnnotationFormatterFactory implementation below binds + The example AnnotationFormatterFactory implementation below binds the @NumberFormat Annotation to a formatter. This annotation allows - either a number style or pattern to be specified: + either a number style or pattern to be specified: { @@ -1338,7 +1339,7 @@ public interface AnnotationFormatterFactory { } }]]> - To trigger formatting, simply annotate fields with @NumberFormat: + To trigger formatting, simply annotate fields with @NumberFormat: {
Format Annotation API - A portable format annotation API exists in the + A portable format annotation API exists in the org.springframework.format.annotation package. Use @NumberFormat to format java.lang.Number fields. Use @DateTimeFormat to format java.util.Date, java.util.Calendar, - java.util.Long, or Joda Time fields. + java.util.Long, or Joda Time fields. - The example below uses @DateTimeFormat to format a java.util.Date - as a ISO Date (yyyy-MM-dd): + The example below uses @DateTimeFormat to format a java.util.Date + as a ISO Date (yyyy-MM-dd): {
FormatterRegistry SPI - The FormatterRegistry is an SPI for registering formatters and + The FormatterRegistry is an SPI for registering formatters and converters. FormattingConversionService is an implementation of FormatterRegistry suitable for most environments. This implementation may be configured programmatically or declaratively @@ -1381,9 +1382,9 @@ public interface AnnotationFormatterFactory { ConversionService, it can be directly configured for use with Spring's DataBinder and the Spring Expression Language (SpEL). - + - Review the FormatterRegistry SPI below: + Review the FormatterRegistry SPI below: - As shown above, Formatters can be registered by fieldType or + As shown above, Formatters can be registered by fieldType or annotation. - - The FormatterRegistry SPI allows you to configure Formatting rules + + The FormatterRegistry SPI allows you to configure Formatting rules centrally, instead of duplicating such configuration across your Controllers. For example, you might want to enforce that all Date fields are formatted a certain way, or fields with a specific annotation are formatted in a certain way. With a shared FormatterRegistry, you define these rules once and they are applied whenever formatting is needed. - +
FormatterRegistrar SPI - The FormatterRegistrar is an SPI for registering formatters and + The FormatterRegistrar is an SPI for registering formatters and converters through the FormatterRegistry: - + - A FormatterRegistrar is useful when registering multiple related + A FormatterRegistrar is useful when registering multiple related converters and formatters for a given formatting category, such as Date formatting. It can also be useful where declarative registration is insufficient. For example when a formatter needs to be indexed under a specific field type different from its own <T> or when registering a Printer/Parser pair. The next section provides more information on converter and formatter registration. - +
Configuring Formatting in Spring MVC - In a Spring MVC application, you may configure a custom + In a Spring MVC application, you may configure a custom ConversionService instance explicitly as an attribute of the annotation-driven element of the MVC namespace. This ConversionService will then be used anytime a type conversion is required during Controller model binding. If not configured explicitly, Spring MVC will automatically register default formatters and converters - for common types such as numbers and dates. + for common types such as numbers and dates. - To rely on default formatting rules, no custom configuration is - required in your Spring MVC config XML: + To rely on default formatting rules, no custom configuration is + required in your Spring MVC config XML: ]]> - With this one-line of configuration, default formatters for Numbers + With this one-line of configuration, default formatters for Numbers and Date types will be installed, including support for the @NumberFormat and @DateTimeFormat annotations. Full support for the Joda Time formatting library is also installed if Joda Time is present on the classpath. - To inject a ConversionService instance with custom formatters and + To inject a ConversionService instance with custom formatters and converters registered, set the conversion-service attribute and then specify custom converters, formatters, or FormatterRegistrars as properties - of the FormattingConversionServiceFactoryBean: + of the FormattingConversionServiceFactoryBean: ]]> - See and + See and the FormattingConversionServiceFactoryBean for more information on when to use FormatterRegistrars. - +
@@ -1611,31 +1612,31 @@ public class AppConfig {
Spring 3 Validation - Spring 3 introduces several enhancements to its validation support. + Spring 3 introduces several enhancements to its validation support. First, the JSR-303 Bean Validation API is now fully supported. Second, when used programmatically, Spring's DataBinder can now validate objects as well as bind to them. Third, Spring MVC now has support for declaratively - validating @Controller inputs. + validating @Controller inputs.
Overview of the JSR-303 Bean Validation API - JSR-303 standardizes validation constraint declaration and metadata + JSR-303 standardizes validation constraint declaration and metadata for the Java platform. 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 take - advantage of. You may also define your own custom constraints. + advantage of. You may also define your own custom constraints. - To illustrate, consider a simple PersonForm model with two - properties: + To illustrate, consider a simple PersonForm model with two + properties: - JSR-303 allows you to define declarative validation constraints - against such properties: + JSR-303 allows you to define declarative validation constraints + against such properties: - When an instance of this class is validated by a JSR-303 Validator, - these constraints will be enforced. + When an instance of this class is validated by a JSR-303 Validator, + these constraints will be enforced. - For general information on JSR-303, see the Bean Validation - Specification. For information on the specific capabilities of + For general information on JSR-303/JSR-349, see the Bean Validation website. + For information on the specific capabilities of the default reference implementation, see the Hibernate Validator - documentation. To learn how to setup a JSR-303 implementation as a - Spring bean, keep reading. + documentation. To learn how to setup a Bean Validation provider as a + Spring bean, keep reading.
- Configuring a Bean Validation Implementation + Configuring a Bean Validation Provider - 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 for a + Spring provides full support for the Bean Validation API. + This includes convenient support for bootstrapping a JSR-303/JSR-349 + Bean Validation provider as a Spring bean. This allows for a javax.validation.ValidatorFactory or javax.validation.Validator to be injected wherever - validation is needed in your application. + validation is needed in your application. - Use the LocalValidatorFactoryBean to - configure a default JSR-303 Validator as a Spring bean: + Use the LocalValidatorFactoryBean to + configure a default Validator as a Spring bean: ]]> - The basic configuration above will trigger JSR-303 to initialize - using its default bootstrap mechanism. A JSR-303 provider, such as + The basic configuration above will trigger Bean Validation to initialize + using its default bootstrap mechanism. A JSR-303/JSR-349 provider, such as Hibernate Validator, is expected to be present in the classpath and will - be detected automatically. + be detected automatically.
Injecting a Validator - LocalValidatorFactoryBean implements both + LocalValidatorFactoryBean implements both javax.validation.ValidatorFactory and javax.validation.Validator, as well as Spring's org.springframework.validation.Validator. You may inject a reference to either of these interfaces into beans that need to - invoke validation logic. + invoke validation logic. - Inject a reference to javax.validation.Validator if - you prefer to work with the JSR-303 API directly: + Inject a reference to javax.validation.Validator if + you prefer to work with the Bean Validation API directly: - Inject a reference to + Inject a reference to org.springframework.validation.Validator if your bean - requires the Spring Validation API: + requires the Spring Validation API: Configuring Custom Constraints - Each JSR-303 validation constraint consists of two parts. First, + Each Bean Validation constraint consists of two parts. First, a @Constraint annotation that declares the constraint and its configurable properties. Second, an implementation of the javax.validation.ConstraintValidator interface that @@ -1729,17 +1730,17 @@ public class MyService { corresponding ValidationConstraint implementation class. At runtime, a ConstraintValidatorFactory instantiates the referenced implementation when the constraint annotation is encountered in your - domain model. + domain model. - By default, the LocalValidatorFactoryBean + By default, the LocalValidatorFactoryBean configures a SpringConstraintValidatorFactory that uses Spring to create ConstraintValidator instances. This allows your custom ConstraintValidators to benefit from dependency injection like - any other Spring bean. + any other Spring bean. - Shown below is an example of a custom @Constraint declaration, + Shown below is an example of a custom @Constraint declaration, followed by an associated ConstraintValidator - implementation that uses Spring for dependency injection: + implementation that uses Spring for dependency injection: - As you can see, a ConstraintValidator implementation may have its - dependencies @Autowired like any other Spring bean. + As you can see, a ConstraintValidator implementation may have its + dependencies @Autowired like any other Spring bean.
Additional Configuration Options - The default LocalValidatorFactoryBean + The default LocalValidatorFactoryBean configuration should prove sufficient for most cases. There are a - number of other configuration options for various JSR-303 constructs, + number of configuration options for various Bean Validation constructs, from message interpolation to traversal resolution. See the JavaDocs of LocalValidatorFactoryBean for more - information on these options. + information on these options.
Configuring a DataBinder - Since Spring 3, a DataBinder instance can be configured with a + Since Spring 3, a DataBinder instance can be configured with a Validator. Once configured, the Validator may be invoked by calling binder.validate(). Any validation Errors are automatically - added to the binder's BindingResult. + added to the binder's BindingResult. - When working with the DataBinder programmatically, this can be used - to invoke validation logic after binding to a target object: + When working with the DataBinder programmatically, this can be used + to invoke validation logic after binding to a target object: Foo target = new Foo(); DataBinder binder = new DataBinder(target); @@ -1797,11 +1798,11 @@ binder.validate(); // get BindingResult that includes any validation errors BindingResult results = binder.getBindingResult(); - A DataBinder can also be configured with multiple + A DataBinder can also be configured with multiple Validator instances via dataBinder.addValidators and dataBinder.replaceValidators. - This is useful when combining globally configured JSR-303 Bean Validation + This is useful when combining globally configured Bean Validation with a Spring Validator configured locally on a DataBinder instance. See . @@ -1811,15 +1812,15 @@ BindingResult results = binder.getBindingResult();
Spring MVC 3 Validation - Beginning with Spring 3, Spring MVC has the ability to + Beginning with Spring 3, Spring MVC has the ability to automatically validate @Controller inputs. In previous versions it was - up to the developer to manually invoke validation logic. + up to the developer to manually invoke validation logic.
Triggering @Controller Input Validation - To trigger validation of a @Controller input, simply annotate the - input argument as @Valid: + To trigger validation of a @Controller input, simply annotate the + input argument as @Valid: @Controller public class MyController { @@ -1827,22 +1828,22 @@ public class MyController { @RequestMapping("/foo", method=RequestMethod.POST) public void processFoo(@Valid Foo foo) { /* ... */ } - Spring MVC will validate a @Valid object after binding so-long as - an appropriate Validator has been configured. + 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 is not a Spring-specific construct. + The @Valid annotation is part of the standard JSR-303 Bean + Validation API, and is not a Spring-specific construct.
Configuring a Validator for use by Spring MVC - The Validator instance invoked when a @Valid method argument is + The Validator instance invoked when a @Valid method argument is encountered may be configured in two ways. First, you may call binder.setValidator(Validator) within a @Controller's @InitBinder callback. This allows you to configure a Validator instance per - @Controller class: + @Controller class: - Second, you may call setValidator(Validator) on the global + Second, you may call setValidator(Validator) on the global WebBindingInitializer. This allows you to configure a Validator instance across all @Controllers. This can be achieved easily by using - the Spring MVC namespace: + the Spring MVC namespace: ]]> - To combine a global and a local validator, configure the + To combine a global and a local validator, configure the global validator as shown above and then add a local validator:
- Configuring a JSR-303 Validator for use by Spring MVC + Configuring a JSR-303/JSR-349 Validator for use by Spring MVC - With JSR-303, a single javax.validation.Validator + With Bean Validation, a single javax.validation.Validator instance typically validates all model objects - that declare validation constraints. To configure a JSR-303-backed - Validator with Spring MVC, simply add a JSR-303 Provider, such as + that declare validation constraints. To configure such a JSR-303 backed + Validator with Spring MVC, simply add a Bean Validation provider, such as Hibernate Validator, to your classpath. Spring MVC will detect it and - automatically enable JSR-303 support across all Controllers. + automatically enable Bean Validation support across all Controllers. - The Spring MVC configuration required to enable JSR-303 support - is shown below: + The Spring MVC configuration required to enable Bean Validation support + is shown below: - + ]]> - With this minimal configuration, anytime a @Valid @Controller - input is encountered, it will be validated by the JSR-303 provider. - JSR-303, in turn, will enforce any constraints declared against the - input. Any ConstraintViolations will automatically be exposed as + With this minimal configuration, anytime a @Valid @Controller input + is encountered, it will be validated by the Bean Validation provider. + That provider, in turn, will enforce any constraints declared against + the input. Any ConstraintViolations will automatically be exposed as errors in the BindingResult renderable by standard Spring MVC form - tags. + tags.