[[validation]] = Validation, Data Binding, and Type Conversion [[validation-introduction]] == Introduction .JSR-303/JSR-349 Bean Validation **** 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 Bean Validation once globally, as described in <>, and use it exclusively for all validation needs. An application can also register additional Spring `Validator` instances per `DataBinder` instance, as described in <>. This may be useful for plugging in validation logic without the use of annotations. **** There are pros and cons for considering validation as business logic, and Spring offers 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, 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 and 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 process user input). Spring provides the so-called `DataBinder` to do exactly that. The `Validator` and the `DataBinder` make up the `validation` package, which is primarily used in but not limited to the MVC framework. The `BeanWrapper` is a fundamental concept in the Spring Framework and is used in a lot of places. However, you probably will not have the need to use the `BeanWrapper` directly. Because this is reference documentation however, we felt that some explanation might be in order. We will explain the `BeanWrapper` in this chapter since, if you were going to use it at all, you would most likely do so when trying to bind data to objects. Spring's DataBinder and the lower-level BeanWrapper both use PropertyEditors to parse and format property values. The `PropertyEditor` concept is part of the JavaBeans specification, and is also explained in this chapter. Spring 3 introduces a "core.convert" package that provides a general type conversion facility, as well as a higher-level "format" package for formatting UI field values. These new packages may be used as simpler alternatives to PropertyEditors, and will also be discussed in this chapter. [[validator]] == Validation using Spring's Validator interface Spring features a `Validator` interface that you can use to validate objects. The `Validator` interface works using an `Errors` object so that while validating, validators can report validation failures to the `Errors` object. Let's consider a small data object: [source,java,indent=0] [subs="verbatim,quotes"] ---- public class Person { private String name; private int age; // the usual getters and setters... } ---- We're going to provide validation behavior for the `Person` class by implementing the following two methods of the `org.springframework.validation.Validator` interface: * `supports(Class)` - Can this `Validator` validate instances of the supplied `Class`? * `validate(Object, org.springframework.validation.Errors)` - validates the given object and in case of validation errors, registers those with the given `Errors` object Implementing a `Validator` is fairly straightforward, especially when you know of the `ValidationUtils` helper class that the Spring Framework also provides. [source,java,indent=0] [subs="verbatim"] ---- public class PersonValidator implements Validator { /** * This Validator validates *just* Person instances */ public boolean supports(Class clazz) { return Person.class.equals(clazz); } public void validate(Object obj, Errors e) { ValidationUtils.rejectIfEmpty(e, "name", "name.empty"); Person p = (Person) obj; if (p.getAge() < 0) { e.rejectValue("age", "negativevalue"); } else if (p.getAge() > 110) { e.rejectValue("age", "too.darn.old"); } } } ---- As you can see, the `static` `rejectIfEmpty(..)` method on the `ValidationUtils` class is used to reject the `'name'` property if it is `null` or the empty string. Have a look at the `ValidationUtils` javadocs to see what functionality it provides besides the example shown previously. While it is certainly possible to implement a single `Validator` class to validate each of the nested objects in a rich object, it may be better to encapsulate the validation logic for each nested class of object in its own `Validator` implementation. A simple example of a __'rich'__ object would be a `Customer` that is composed of two `String` properties (a first and second name) and a complex `Address` object. `Address` objects may be used independently of `Customer` objects, and so a distinct `AddressValidator` has been implemented. If you want your `CustomerValidator` to reuse the logic contained within the `AddressValidator` class without resorting to copy-and-paste, you can dependency-inject or instantiate an `AddressValidator` within your `CustomerValidator`, and use it like so: [source,java,indent=0] [subs="verbatim,quotes"] ---- public class CustomerValidator implements Validator { private final Validator addressValidator; public CustomerValidator(Validator addressValidator) { if (addressValidator == null) { throw new IllegalArgumentException("The supplied [Validator] is " + "required and must not be null."); } if (!addressValidator.supports(Address.class)) { throw new IllegalArgumentException("The supplied [Validator] must " + support the validation of [Address] instances."); } this.addressValidator = addressValidator; } /** * This Validator validates Customer instances, and any subclasses of Customer too */ public boolean supports(Class clazz) { return Customer.class.isAssignableFrom(clazz); } public void validate(Object target, Errors errors) { ValidationUtils.rejectIfEmptyOrWhitespace(errors, "firstName", "field.required"); ValidationUtils.rejectIfEmptyOrWhitespace(errors, "surname", "field.required"); Customer customer = (Customer) target; try { errors.pushNestedPath("address"); ValidationUtils.invokeValidator(this.addressValidator, customer.getAddress(), errors); } finally { errors.popNestedPath(); } } } ---- Validation errors are reported to the `Errors` object passed to the validator. In case of Spring Web MVC you can use `` tag to inspect the error messages, but of course you can also inspect the errors object yourself. More information about the methods it offers can be found in the javadocs. [[validation-conversion]] == Resolving codes to error messages We've talked about databinding and validation. Outputting messages corresponding to validation errors is the last thing we need to discuss. In the example we've shown above, we rejected the `name` and the `age` field. If we're going to output the error messages by using a `MessageSource`, we will do so using the error code we've given when rejecting the field ('name' and 'age' in this case). When you call (either directly, or indirectly, using for example the `ValidationUtils` class) `rejectValue` or one of the other `reject` methods from the `Errors` interface, the underlying implementation will not only register the code you've passed in, but also a number of additional error codes. What error codes it registers is determined by the `MessageCodesResolver` that is used. By default, the `DefaultMessageCodesResolver` is used, which for example not only registers a message with the code you gave, but also messages that include the field name you passed to the reject method. So in case you reject a field using `rejectValue("age", "too.darn.old")`, apart from the `too.darn.old` code, Spring will also register `too.darn.old.age` and `too.darn.old.age.int` (so the first will include the field name and the second will include the type of the field); this is done as a convenience to aid developers in targeting error messages and suchlike. More information on the `MessageCodesResolver` and the default strategy can be found online in the javadocs of {api-spring-framework}/validation/MessageCodesResolver.html[`MessageCodesResolver`] and {api-spring-framework}/validation/DefaultMessageCodesResolver.html[`DefaultMessageCodesResolver`], respectively. [[beans-beans]] == Bean manipulation and the BeanWrapper The `org.springframework.beans` package adheres to the JavaBeans standard provided by Oracle. A JavaBean is simply a class with a default no-argument constructor, which follows a naming convention where (by way of an example) a property named `bingoMadness` would have a setter method `setBingoMadness(..)` and a getter method `getBingoMadness()`. For more information about JavaBeans and the specification, please refer to Oracle's website ( http://docs.oracle.com/javase/6/docs/api/java/beans/package-summary.html[javabeans]). One quite important class in the beans package is the `BeanWrapper` interface and its corresponding implementation ( `BeanWrapperImpl`). As quoted from the javadocs, the `BeanWrapper` offers functionality to set and get property values (individually or in bulk), get property descriptors, and to query properties to determine if they are readable or writable. Also, the `BeanWrapper` offers support for nested properties, enabling the setting of properties on sub-properties to an unlimited depth. Then, the `BeanWrapper` supports the ability to add standard JavaBeans `PropertyChangeListeners` and `VetoableChangeListeners`, without the need for supporting code in the target class. Last but not least, the `BeanWrapper` provides support for the setting of indexed properties. The `BeanWrapper` usually isn't used by application code directly, but by the `DataBinder` and the `BeanFactory`. The way the `BeanWrapper` works is partly indicated by its name: __it wraps a bean__ to perform actions on that bean, like setting and retrieving properties. [[beans-beans-conventions]] === Setting and getting basic and nested properties Setting and getting properties is done using the `setPropertyValue(s)` and `getPropertyValue(s)` methods that both come with a couple of overloaded variants. They're all described in more detail in the javadocs Spring comes with. What's important to know is that there are a couple of conventions for indicating properties of an object. A couple of examples: [[beans-beans-conventions-properties-tbl]] .Examples of properties |=== | Expression| Explanation | `name` | Indicates the property `name` corresponding to the methods `getName()` or `isName()` and `setName(..)` | `account.name` | Indicates the nested property `name` of the property `account` corresponding e.g. to the methods `getAccount().setName()` or `getAccount().getName()` | `account[2]` | Indicates the __third__ element of the indexed property `account`. Indexed properties can be of type `array`, `list` or other __naturally ordered__ collection | `account[COMPANYNAME]` | Indicates the value of the map entry indexed by the key __COMPANYNAME__ of the Map property `account` |=== Below you'll find some examples of working with the `BeanWrapper` to get and set properties. __(This next section is not vitally important to you if you're not planning to work with the `BeanWrapper` directly. If you're just using the `DataBinder` and the `BeanFactory` and their out-of-the-box implementation, you should skip ahead to the section about `PropertyEditors`.)__ Consider the following two classes: [source,java,indent=0] [subs="verbatim,quotes"] ---- public class Company { private String name; private Employee managingDirector; public String getName() { return this.name; } public void setName(String name) { this.name = name; } public Employee getManagingDirector() { return this.managingDirector; } public void setManagingDirector(Employee managingDirector) { this.managingDirector = managingDirector; } } ---- [source,java,indent=0] [subs="verbatim,quotes"] ---- public class Employee { private String name; private float salary; public String getName() { return this.name; } public void setName(String name) { this.name = name; } public float getSalary() { return salary; } public void setSalary(float salary) { this.salary = salary; } } ---- The following code snippets show some examples of how to retrieve and manipulate some of the properties of instantiated `Companies` and `Employees`: [source,java,indent=0] [subs="verbatim,quotes"] ---- BeanWrapper company = new BeanWrapperImpl(new Company()); // setting the company name.. company.setPropertyValue("name", "Some Company Inc."); // ... can also be done like this: PropertyValue value = new PropertyValue("name", "Some Company Inc."); company.setPropertyValue(value); // ok, let's create the director and tie it to the company: BeanWrapper jim = new BeanWrapperImpl(new Employee()); jim.setPropertyValue("name", "Jim Stravinsky"); company.setPropertyValue("managingDirector", jim.getWrappedInstance()); // retrieving the salary of the managingDirector through the company Float salary = (Float) company.getPropertyValue("managingDirector.salary"); ---- [[beans-beans-conversion]] === Built-in PropertyEditor implementations Spring uses the concept of `PropertyEditors` to effect the conversion between an `Object` and a `String`. If you think about it, it sometimes might be handy to be able to represent properties in a different way than the object itself. For example, a `Date` can be represented in a human readable way (as the `String` ' `2007-14-09`'), while we're still able to convert the human readable form back to the original date (or even better: convert any date entered in a human readable form, back to `Date` objects). This behavior can be achieved by __registering custom editors__, of type `java.beans.PropertyEditor`. Registering custom editors on a `BeanWrapper` or alternately in a specific IoC container as mentioned in the previous chapter, gives it the knowledge of how to convert properties to the desired type. Read more about `PropertyEditors` in the javadocs of the `java.beans` package provided by Oracle. A couple of examples where property editing is used in Spring: * __setting properties on beans__ is done using `PropertyEditors`. When mentioning `java.lang.String` as the value of a property of some bean you're declaring in XML file, Spring will (if the setter of the corresponding property has a `Class`-parameter) use the `ClassEditor` to try to resolve the parameter to a `Class` object. * __parsing HTTP request parameters__ in Spring's MVC framework is done using all kinds of `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 located in the `org.springframework.beans.propertyeditors` package. Most, but not all (as indicated below), are registered by default by `BeanWrapperImpl`. Where the property editor is configurable in some fashion, you can of course still register your own variant to override the default one: [[beans-beans-property-editors-tbl]] .Built-in PropertyEditors |=== | Class| Explanation | `ByteArrayPropertyEditor` | Editor for byte arrays. Strings will simply be converted to their corresponding byte representations. Registered by default by `BeanWrapperImpl`. | `ClassEditor` | Parses Strings representing classes to actual classes and the other way around. When a class is not found, an `IllegalArgumentException` is thrown. Registered by default by `BeanWrapperImpl`. | `CustomBooleanEditor` | Customizable property editor for `Boolean` properties. Registered by default by `BeanWrapperImpl`, but, can be overridden by registering custom instance of it as custom editor. | `CustomCollectionEditor` | Property editor for Collections, converting any source `Collection` to a given target `Collection` type. | `CustomDateEditor` | Customizable property editor for java.util.Date, supporting a custom DateFormat. NOT registered by default. Must be user registered as needed with appropriate format. | `CustomNumberEditor` | Customizable property editor for any Number subclass like `Integer`, `Long`, `Float`, `Double`. Registered by default by `BeanWrapperImpl`, but can be overridden by registering custom instance of it as a custom editor. | `FileEditor` | Capable of resolving Strings to `java.io.File` objects. Registered by default by `BeanWrapperImpl`. | `InputStreamEditor` | One-way property editor, capable of taking a text string and producing (via an intermediate `ResourceEditor` and `Resource`) an `InputStream`, so `InputStream` properties may be directly set as Strings. Note that the default usage will not close the `InputStream` for you! Registered by default by `BeanWrapperImpl`. | `LocaleEditor` | Capable of resolving Strings to `Locale` objects and vice versa (the String format is [language]_[country]_[variant], which is the same thing the toString() method of Locale provides). Registered by default by `BeanWrapperImpl`. | `PatternEditor` | Capable of resolving Strings to `java.util.regex.Pattern` objects and vice versa. | `PropertiesEditor` | Capable of converting Strings (formatted using the format as defined in the javadocs of the `java.util.Properties` class) to `Properties` objects. Registered by default by `BeanWrapperImpl`. | `StringTrimmerEditor` | Property editor that trims Strings. Optionally allows transforming an empty string into a `null` value. NOT registered by default; must be user registered as needed. | `URLEditor` | Capable of resolving a String representation of a URL to an actual `URL` object. Registered by default by `BeanWrapperImpl`. |=== 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 `PropertyEditor` implementations for types such as `Font`, `Color`, and most of the primitive types. Note also that the standard JavaBeans infrastructure will automatically discover `PropertyEditor` classes (without you having to register them explicitly) if they are in the same package as the class they handle, and have the same name as that class, with `'Editor'` appended; for example, one could have the following class and package structure, which would be sufficient for the `FooEditor` class to be recognized and used as the `PropertyEditor` for `Foo`-typed properties. [literal] [subs="verbatim,quotes"] ---- com chank pop Foo FooEditor // the PropertyEditor for the Foo class ---- Note that you can also use the standard `BeanInfo` JavaBeans mechanism here as well (described http://docs.oracle.com/javase/tutorial/javabeans/advanced/customization.html[in not-amazing-detail here]). Find below an example of using the `BeanInfo` mechanism for explicitly registering one or more `PropertyEditor` instances with the properties of an associated class. [literal] [subs="verbatim,quotes"] ---- com chank pop Foo FooBeanInfo // the BeanInfo for the Foo class ---- Here is the Java source code for the referenced `FooBeanInfo` class. This would associate a `CustomNumberEditor` with the `age` property of the `Foo` class. [source,java,indent=0] [subs="verbatim,quotes"] ---- public class FooBeanInfo extends SimpleBeanInfo { public PropertyDescriptor[] getPropertyDescriptors() { try { final PropertyEditor numberPE = new CustomNumberEditor(Integer.class, true); PropertyDescriptor ageDescriptor = new PropertyDescriptor("age", Foo.class) { public PropertyEditor createPropertyEditor(Object bean) { return numberPE; }; }; return new PropertyDescriptor[] { ageDescriptor }; } catch (IntrospectionException ex) { throw new Error(ex.toString()); } } } ---- [[beans-beans-conversion-customeditor-registration]] ==== Registering additional custom PropertyEditors When setting bean properties as a string value, a Spring IoC container ultimately uses standard JavaBeans `PropertyEditors` to convert these Strings to the complex type of the property. Spring pre-registers a number of custom `PropertyEditors` (for example, to convert a classname expressed as a string into a real `Class` object). Additionally, Java's standard JavaBeans `PropertyEditor` lookup mechanism allows a `PropertyEditor` for a class simply to be named appropriately and placed in the same package as the class it provides support for, to be found automatically. If there is a need to register other custom `PropertyEditors`, there are several mechanisms available. The most manual approach, which is not normally convenient or recommended, is to simply use the `registerCustomEditor()` method of the `ConfigurableBeanFactory` interface, assuming you have a `BeanFactory` reference. Another, slightly more convenient, mechanism is to use a special bean factory post-processor called `CustomEditorConfigurer`. Although bean factory post-processors can be used with `BeanFactory` implementations, the `CustomEditorConfigurer` has a nested property setup, so it is strongly recommended that it is used with the `ApplicationContext`, where it may be deployed in similar fashion to any other bean, and automatically detected and applied. Note that all bean factories and application contexts automatically use a number of built-in property editors, through their use of something called a `BeanWrapper` to handle property conversions. The standard property editors that the `BeanWrapper` registers are listed in <>. Additionally, `ApplicationContexts` also override or add an additional number of editors to handle resource lookups in a manner appropriate to the specific application context type. Standard JavaBeans `PropertyEditor` instances are used to convert property values expressed as strings to the actual complex type of the property. `CustomEditorConfigurer`, a bean factory post-processor, may be used to conveniently add support for additional `PropertyEditor` instances to an `ApplicationContext`. Consider a user class `ExoticType`, and another class `DependsOnExoticType` which needs `ExoticType` set as a property: [source,java,indent=0] [subs="verbatim,quotes"] ---- package example; public class ExoticType { private String name; public ExoticType(String name) { this.name = name; } } public class DependsOnExoticType { private ExoticType type; public void setType(ExoticType type) { this.type = type; } } ---- When things are properly set up, we want to be able to assign the type property as a string, which a `PropertyEditor` will behind the scenes convert into an actual `ExoticType` instance: [source,xml,indent=0] [subs="verbatim,quotes"] ---- ---- The `PropertyEditor` implementation could look similar to this: [source,java,indent=0] [subs="verbatim,quotes"] ---- // converts string representation to ExoticType object package example; public class ExoticTypeEditor extends PropertyEditorSupport { public void setAsText(String text) { setValue(new ExoticType(text.toUpperCase())); } } ---- Finally, we use `CustomEditorConfigurer` to register the new `PropertyEditor` with the `ApplicationContext`, which will then be able to use it as needed: [source,xml,indent=0] [subs="verbatim,quotes"] ---- ---- [[beans-beans-conversion-customeditor-registration-per]] ===== Using PropertyEditorRegistrars Another mechanism for registering property editors with the Spring container is to create and use a `PropertyEditorRegistrar`. This interface is particularly useful when you need to use the same set of property editors in several different situations: write a corresponding registrar and reuse that in each case. `PropertyEditorRegistrars` work in conjunction with an interface called `PropertyEditorRegistry`, an interface that is implemented by the Spring `BeanWrapper` (and `DataBinder`). `PropertyEditorRegistrars` are particularly convenient when used in conjunction with the `CustomEditorConfigurer` (introduced <>), which exposes a property called `setPropertyEditorRegistrars(..)`: `PropertyEditorRegistrars` added to a `CustomEditorConfigurer` in this fashion can easily be shared with `DataBinder` and Spring MVC `Controllers`. Furthermore, it avoids the need for synchronization on custom editors: a `PropertyEditorRegistrar` is expected to create fresh `PropertyEditor` instances for each bean creation attempt. Using a `PropertyEditorRegistrar` is perhaps best illustrated with an example. First off, you need to create your own `PropertyEditorRegistrar` implementation: [source,java,indent=0] [subs="verbatim,quotes"] ---- package com.foo.editors.spring; public final class CustomPropertyEditorRegistrar implements PropertyEditorRegistrar { public void registerCustomEditors(PropertyEditorRegistry registry) { // it is expected that new PropertyEditor instances are created registry.registerCustomEditor(ExoticType.class, new ExoticTypeEditor()); // you could register as many custom property editors as are required here... } } ---- See also the `org.springframework.beans.support.ResourceEditorRegistrar` for an example `PropertyEditorRegistrar` implementation. Notice how in its implementation of the `registerCustomEditors(..)` method it creates new instances of each property editor. Next we configure a `CustomEditorConfigurer` and inject an instance of our `CustomPropertyEditorRegistrar` into it: [source,xml,indent=0] [subs="verbatim,quotes"] ---- ---- Finally, and in a bit of a departure from the focus of this chapter, for those of you using <>, using `PropertyEditorRegistrars` in conjunction with data-binding `Controllers` (such as `SimpleFormController`) can be very convenient. Find below an example of using a `PropertyEditorRegistrar` in the implementation of an `initBinder(..)` method: [source,java,indent=0] [subs="verbatim,quotes"] ---- public final class RegisterUserController extends SimpleFormController { private final PropertyEditorRegistrar customPropertyEditorRegistrar; public RegisterUserController(PropertyEditorRegistrar propertyEditorRegistrar) { this.customPropertyEditorRegistrar = propertyEditorRegistrar; } protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception { **this.customPropertyEditorRegistrar.registerCustomEditors(binder);** } // other methods to do with registering a User } ---- This style of `PropertyEditor` registration can lead to concise code (the implementation of `initBinder(..)` is just one line long!), and allows common `PropertyEditor` registration code to be encapsulated in a class and then shared amongst as many `Controllers` as needed. [[core-convert]] == Spring Type Conversion 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. [[core-convert-Converter-API]] === Converter SPI The SPI to implement type conversion logic is simple and strongly typed: [source,java,indent=0] [subs="verbatim,quotes"] ---- package org.springframework.core.convert.converter; public interface Converter { T convert(S source); } ---- 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. Such a converter can also be applied transparently if a collection or array of `S` needs to be converted to an array or collection of `T`, provided that a delegating array/collection converter has been registered as well (which `DefaultConversionService` does by default). For each call to `convert(S)`, the source argument is guaranteed to be NOT null. Your Converter may throw any unchecked exception if conversion fails; specifically, an `IllegalArgumentException` should be thrown to report an invalid source value. Take care to ensure that your `Converter` implementation is thread-safe. 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 for a typical `Converter` implementation: [source,java,indent=0] [subs="verbatim,quotes"] ---- package org.springframework.core.convert.support; final class StringToInteger implements Converter { public Integer convert(String source) { return Integer.valueOf(source); } } ---- [[core-convert-ConverterFactory-SPI]] === ConverterFactory 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`: [source,java,indent=0] [subs="verbatim,quotes"] ---- package org.springframework.core.convert.converter; public interface ConverterFactory { Converter getConverter(Class targetType); } ---- 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), where T is a subclass of R. Consider the `StringToEnum` ConverterFactory as an example: [source,java,indent=0] [subs="verbatim,quotes"] ---- package org.springframework.core.convert.support; final class StringToEnumConverterFactory implements ConverterFactory { public Converter getConverter(Class targetType) { return new StringToEnumConverter(targetType); } private final class StringToEnumConverter implements Converter { private Class enumType; public StringToEnumConverter(Class enumType) { this.enumType = enumType; } public T convert(String source) { return (T) Enum.valueOf(this.enumType, source.trim()); } } } ---- [[core-convert-GenericConverter-SPI]] === GenericConverter 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. [source,java,indent=0] [subs="verbatim,quotes"] ---- package org.springframework.core.convert.converter; public interface GenericConverter { public Set getConvertibleTypes(); Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType); } ---- 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. 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. [NOTE] ==== Because GenericConverter is a more complex SPI interface, only use it when you need it. Favor Converter or ConverterFactory for basic type conversion needs. ==== [[core-convert-ConditionalGenericConverter-SPI]] ==== ConditionalGenericConverter 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 a `static valueOf` method, is defined on the target class. `ConditionalGenericConverter` is the union of the `GenericConverter` and `ConditionalConverter` interfaces that allows you to define such custom matching criteria: [source,java,indent=0] [subs="verbatim,quotes"] ---- public interface ConditionalGenericConverter extends GenericConverter, ConditionalConverter { boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType); } ---- 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)`. [[core-convert-ConversionService-API]] === ConversionService API The ConversionService defines a unified API for executing type conversion logic at runtime. Converters are often executed behind this facade interface: [source,java,indent=0] [subs="verbatim,quotes"] ---- package org.springframework.core.convert; public interface ConversionService { boolean canConvert(Class sourceType, Class targetType); T convert(Object source, Class targetType); boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType); Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType); } ---- 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. 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. [[core-convert-Spring-config]] === Configuring a ConversionService 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. [NOTE] ==== 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`: [source,xml,indent=0] [subs="verbatim,quotes"] ---- ---- 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. [source,xml,indent=0] [subs="verbatim,quotes"] ---- ---- It is also common to use a ConversionService within a Spring MVC application. See <> in the Spring MVC chapter. In certain situations you may wish to apply formatting during conversion. See <> for details on using `FormattingConversionServiceFactoryBean`. [[core-convert-programmatic-usage]] === Using a ConversionService programmatically To work with a ConversionService instance programmatically, simply inject a reference to it like you would for any other bean: [source,java,indent=0] [subs="verbatim,quotes"] ---- @Service public class MyService { @Autowired public MyService(ConversionService conversionService) { this.conversionService = conversionService; } public void doIt() { this.conversionService.convert(...) } } ---- For most use cases, the `convert` method specifying the _targetType_ can be used but it will not work with more complex types such as a collection of a parameterized element. If you want to convert a `List` of `Integer` to a `List` of `String` programmatically, for instance, you need to provide a formal definition of the source and target types. Fortunately, `TypeDescriptor` provides various options to make that straightforward: [source,java,indent=0] [subs="verbatim,quotes"] ---- DefaultConversionService cs = new DefaultConversionService(); List input = .... cs.convert(input, TypeDescriptor.forObject(input), // List type descriptor TypeDescriptor.collection(List.class, TypeDescriptor.valueOf(String.class))); ---- Note that `DefaultConversionService` registers converters automatically which are appropriate for most environments. This includes collection converters, scalar converters, and also basic `Object` to `String` converters. The same converters can be registered with any `ConverterRegistry` using the _static_ `addDefaultConverters` method on the `DefaultConversionService` class. Converters for value types will be reused for arrays and collections, so there is no need to create a specific converter to convert from a `Collection` of `S` to a `Collection` of `T`, assuming that standard collection handling is appropriate. [[format]] == Spring Field Formatting As discussed in the previous section, <> 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 type to another. A Spring Container uses this system to bind bean property values. In addition, both the Spring Expression Language (SpEL) and DataBinder use this system to bind field values. For example, when SpEL 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. 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 support the view rendering process. In addition, you often need to localize String values. The more general __core.convert__ 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. 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. [[format-Formatter-SPI]] === Formatter SPI The Formatter SPI to implement field formatting logic is simple and strongly typed: [source,java,indent=0] [subs="verbatim,quotes"] ---- package org.springframework.format; public interface Formatter extends Printer, Parser { } ---- Where Formatter extends from the Printer and Parser building-block interfaces: [source,java,indent=0] [subs="verbatim,quotes"] ---- public interface Printer { String print(T fieldValue, Locale locale); } ---- [source,java,indent=0] [subs="verbatim,quotes"] ---- import java.text.ParseException; public interface Parser { T parse(String clientValue, Locale locale) throws ParseException; } ---- 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 for display in the client locale. Implement the `parse()` operation to parse an instance of T from 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. 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` objects using a `java.text.NumberFormat`. The `datetime` package provides a `DateFormatter` to format `java.util.Date` objects with a `java.text.DateFormat`. The `datetime.joda` package provides comprehensive datetime formatting support based on the http://joda-time.sourceforge.net[Joda Time library]. Consider `DateFormatter` as an example `Formatter` implementation: [source,java,indent=0] [subs="verbatim,quotes"] ---- package org.springframework.format.datetime; public final class DateFormatter implements Formatter { private String pattern; public DateFormatter(String pattern) { this.pattern = pattern; } public String print(Date date, Locale locale) { if (date == null) { return ""; } return getDateFormat(locale).format(date); } public Date parse(String formatted, Locale locale) throws ParseException { if (formatted.length() == 0) { return null; } return getDateFormat(locale).parse(formatted); } protected DateFormat getDateFormat(Locale locale) { DateFormat dateFormat = new SimpleDateFormat(this.pattern, locale); dateFormat.setLenient(false); return dateFormat; } } ---- The Spring team welcomes community-driven `Formatter` contributions; see https://jira.spring.io/browse/SPR[jira.spring.io] to contribute. [[format-CustomFormatAnnotations]] === Annotation-driven Formatting As you will see, field formatting can be configured by field type or annotation. To bind an Annotation to a formatter, implement AnnotationFormatterFactory: [source,java,indent=0] [subs="verbatim,quotes"] ---- package org.springframework.format; public interface AnnotationFormatterFactory { Set> getFieldTypes(); Printer getPrinter(A annotation, Class fieldType); Parser getParser(A annotation, Class fieldType); } ---- 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. The example AnnotationFormatterFactory implementation below binds the @NumberFormat Annotation to a formatter. This annotation allows either a number style or pattern to be specified: [source,java,indent=0] [subs="verbatim,quotes"] ---- public final class NumberFormatAnnotationFormatterFactory implements AnnotationFormatterFactory { public Set> getFieldTypes() { return new HashSet>(asList(new Class[] { Short.class, Integer.class, Long.class, Float.class, Double.class, BigDecimal.class, BigInteger.class })); } public Printer getPrinter(NumberFormat annotation, Class fieldType) { return configureFormatterFrom(annotation, fieldType); } public Parser getParser(NumberFormat annotation, Class fieldType) { return configureFormatterFrom(annotation, fieldType); } private Formatter configureFormatterFrom(NumberFormat annotation, Class fieldType) { if (!annotation.pattern().isEmpty()) { return new NumberFormatter(annotation.pattern()); } else { Style style = annotation.style(); if (style == Style.PERCENT) { return new PercentFormatter(); } else if (style == Style.CURRENCY) { return new CurrencyFormatter(); } else { return new NumberFormatter(); } } } } ---- To trigger formatting, simply annotate fields with @NumberFormat: [source,java,indent=0] [subs="verbatim,quotes"] ---- public class MyModel { @NumberFormat(style=Style.CURRENCY) private BigDecimal decimal; } ---- [[format-annotations-api]] ==== Format Annotation API 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. The example below uses @DateTimeFormat to format a java.util.Date as a ISO Date (yyyy-MM-dd): [source,java,indent=0] [subs="verbatim,quotes"] ---- public class MyModel { @DateTimeFormat(iso=ISO.DATE) private Date date; } ---- [[format-FormatterRegistry-SPI]] === FormatterRegistry SPI 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 as a Spring bean using `FormattingConversionServiceFactoryBean`. Because this implementation also implements `ConversionService`, it can be directly configured for use with Spring's DataBinder and the Spring Expression Language (SpEL). Review the FormatterRegistry SPI below: [source,java,indent=0] [subs="verbatim,quotes"] ---- package org.springframework.format; public interface FormatterRegistry extends ConverterRegistry { void addFormatterForFieldType(Class fieldType, Printer printer, Parser parser); void addFormatterForFieldType(Class fieldType, Formatter formatter); void addFormatterForFieldType(Formatter formatter); void addFormatterForAnnotation(AnnotationFormatterFactory factory); } ---- As shown above, Formatters can be registered by fieldType or annotation. 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. [[format-FormatterRegistrar-SPI]] === FormatterRegistrar SPI The FormatterRegistrar is an SPI for registering formatters and converters through the FormatterRegistry: [source,java,indent=0] [subs="verbatim,quotes"] ---- package org.springframework.format; public interface FormatterRegistrar { void registerFormatters(FormatterRegistry registry); } ---- 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 or when registering a Printer/Parser pair. The next section provides more information on converter and formatter registration. [[format-configuring-formatting-mvc]] === Configuring Formatting in Spring MVC See <> in the Spring MVC chapter. [[format-configuring-formatting-globaldatetimeformat]] == Configuring a global date & time format By default, date and time fields that are not annotated with `@DateTimeFormat` are converted from strings using the the `DateFormat.SHORT` style. If you prefer, you can change this by defining your own global format. You will need to ensure that Spring does not register default formatters, and instead you should register all formatters manually. Use the `org.springframework.format.datetime.joda.JodaTimeFormatterRegistrar` or `org.springframework.format.datetime.DateFormatterRegistrar` class depending on whether you use the Joda Time library. For example, the following Java configuration will register a global ' `yyyyMMdd`' format. This example does not depend on the Joda Time library: [source,java,indent=0] [subs="verbatim,quotes"] ---- @Configuration public class AppConfig { @Bean public FormattingConversionService conversionService() { // Use the DefaultFormattingConversionService but do not register defaults DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService(false); // Ensure @NumberFormat is still supported conversionService.addFormatterForFieldAnnotation(new NumberFormatAnnotationFormatterFactory()); // Register date conversion with a specific global format DateFormatterRegistrar registrar = new DateFormatterRegistrar(); registrar.setFormatter(new DateFormatter("yyyyMMdd")); registrar.registerFormatters(conversionService); return conversionService; } } ---- If you prefer XML based configuration you can use a `FormattingConversionServiceFactoryBean`. Here is the same example, this time using Joda Time: [source,xml,indent=0] [subs="verbatim,quotes"] ---- ---- [NOTE] ==== Joda Time provides separate distinct types to represent `date`, `time` and `date-time` values. The `dateFormatter`, `timeFormatter` and `dateTimeFormatter` properties of the `JodaTimeFormatterRegistrar` should be used to configure the different formats for each type. The `DateTimeFormatterFactoryBean` provides a convenient way to create formatters. ==== If you are using Spring MVC remember to explicitly configure the conversion service that is used. For Java based `@Configuration` this means extending the `WebMvcConfigurationSupport` class and overriding the `mvcConversionService()` method. For XML you should use the `'conversion-service'` attribute of the `mvc:annotation-driven` element. See <> for details. [[validation-beanvalidation]] == Spring Validation 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. [[validation-beanvalidation-overview]] === Overview of the JSR-303 Bean Validation API 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. To illustrate, consider a simple PersonForm model with two properties: [source,java,indent=0] [subs="verbatim,quotes"] ---- public class PersonForm { private String name; private int age; } ---- JSR-303 allows you to define declarative validation constraints against such properties: [source,java,indent=0] [subs="verbatim,quotes"] ---- public class PersonForm { @NotNull @Size(max=64) private String name; @Min(0) private int age; } ---- When an instance of this class is validated by a JSR-303 Validator, these constraints will be enforced. For general information on JSR-303/JSR-349, see the http://beanvalidation.org/[Bean 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 setup a Bean Validation provider as a Spring bean, keep reading. [[validation-beanvalidation-spring]] === Configuring a Bean Validation Provider 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. Use the `LocalValidatorFactoryBean` to configure a default Validator as a Spring bean: [source,xml,indent=0] [subs="verbatim,quotes"] ---- ---- 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. [[validation-beanvalidation-spring-inject]] ==== Injecting a Validator `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. Inject a reference to `javax.validation.Validator` if you prefer to work with the Bean Validation API directly: [source,java,indent=0] [subs="verbatim,quotes"] ---- import javax.validation.Validator; @Service public class MyService { @Autowired private Validator validator; ---- Inject a reference to `org.springframework.validation.Validator` if your bean requires the Spring Validation API: [source,java,indent=0] [subs="verbatim,quotes"] ---- import org.springframework.validation.Validator; @Service public class MyService { @Autowired private Validator validator; } ---- [[validation-beanvalidation-spring-constraints]] ==== Configuring Custom Constraints 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 implements the constraint's behavior. To associate a declaration with an implementation, each `@Constraint` annotation references a corresponding ValidationConstraint implementation class. At runtime, a `ConstraintValidatorFactory` instantiates the referenced implementation when the constraint annotation is encountered in your domain model. 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. Shown below is an example of a custom `@Constraint` declaration, followed by an associated `ConstraintValidator` implementation that uses Spring for dependency injection: [source,java,indent=0] [subs="verbatim,quotes"] ---- @Target({ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy=MyConstraintValidator.class) public @interface MyConstraint { } ---- [source,java,indent=0] [subs="verbatim,quotes"] ---- import javax.validation.ConstraintValidator; public class MyConstraintValidator implements ConstraintValidator { @Autowired; private Foo aDependency; ... } ---- As you can see, a ConstraintValidator implementation may have its dependencies @Autowired like any other Spring bean. [[validation-beanvalidation-spring-method]] ==== Spring-driven Method Validation The method validation feature supported by Bean Validation 1.1, and as a custom extension also by Hibernate Validator 4.3, can be integrated into a Spring context through a `MethodValidationPostProcessor` bean definition: [source,xml,indent=0] [subs="verbatim,quotes"] ---- ---- In order to be eligible for Spring-driven method validation, all target classes need to be annotated with Spring's `@Validated` annotation, optionally declaring the validation groups to use. Check out the `MethodValidationPostProcessor` javadocs for setup details with Hibernate Validator and Bean Validation 1.1 providers. [[validation-beanvalidation-spring-other]] ==== Additional Configuration Options The default `LocalValidatorFactoryBean` configuration should prove sufficient for most cases. There are a number of configuration options for various Bean Validation constructs, from message interpolation to traversal resolution. See the `LocalValidatorFactoryBean` javadocs for more information on these options. [[validation-binder]] === Configuring a DataBinder 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. When working with the DataBinder programmatically, this can be used to invoke validation logic after binding to a target object: [source,java,indent=0] [subs="verbatim,quotes"] ---- Foo target = new Foo(); DataBinder binder = new DataBinder(target); binder.setValidator(new FooValidator()); // bind to the target object binder.bind(propertyValues); // validate the target object binder.validate(); // get BindingResult that includes any validation errors BindingResult results = binder.getBindingResult(); ---- A DataBinder can also be configured with multiple `Validator` instances via `dataBinder.addValidators` and `dataBinder.replaceValidators`. This is useful when combining globally configured Bean Validation with a Spring `Validator` configured locally on a DataBinder instance. See <>. [[validation-mvc]] === Spring MVC 3 Validation See <> in the Spring MVC chapter.