diff --git a/spring-framework-reference/src/validation.xml b/spring-framework-reference/src/validation.xml index 4858d2025f8..7931f43a5fb 100644 --- a/spring-framework-reference/src/validation.xml +++ b/spring-framework-reference/src/validation.xml @@ -1464,16 +1464,16 @@ public class MyController {
Spring 3 Object Mapping - There are scenarios, particularly in large message-oriented business applications, where data and object transformation is required. + There are scenarios, particularly in large message-oriented business applications, where object transformation is required. For example, consider a complex Web Service where there is a separation between the data exchange model and the internal domain model used to structure business logic. - In cases like this, a general-purpose data mapping facility can be useful for automating the mapping between these disparate models. + In cases like this, a general-purpose object-to-object mapping facility can be useful for automating the mapping between these disparate models. Spring 3 introduces such a facility built on the Spring Expression Language (SpEL). This facility is described in this section.
Mapper API - The API to implement data mapping logic is simple and strongly typed: + The API to implement object mapping logic is simple and strongly typed: General-purpose SpelMapper Implementation - A general purpose object Mapper implementation exists in the org.springframework.mapping.support package named SpelMapper. - Built on the flexible Spring Expression Language (SpEL), this Mapper is capable of mapping between objects of all types, including JavaBeans, Arrays, Collections, and Maps. - It is also extensible and allows additional MappableTypes to be configured. + A general purpose object-to-object mapping system exists in the org.springframework.mapping.support package. + Built on the flexible Spring Expression Language (SpEL), this system is capable of mapping between a variety of object types, including JavaBeans, Arrays, Collections, and Maps. + It can perform field-to-field, field-to-multi-field, and multi-field to field mappings. + It also can carry out type conversion and recursive mapping, often needed with rich object models.
Usage - To use a SpelMapper with its default configuration, simply construct one and call map: + To obtain a general purpose object Mapper with its default configuration, simply call MappingFactory.getDefaultMapper(). + Then invoke the Mapper by calling its map(Object, Object) operation: +MappingFactory.defaultMapper().map(aSource, aTarget);]]> + - By default, SpelMapper will map the fields on the source and target that have the same names. + By default, the defaultMapper will map the fields on the source and target that have the same names. If the field types differ, the mapping system will attempt a type conversion using Spring 3's type conversion system. Nested bean properties are mapped recursively. Any mapping failures will trigger a MappingException to be thrown. @@ -1562,7 +1564,7 @@ public class Account { } }]]> - Used in the following test case: + Now used in the following test case: Registering Explicit Mappings - When default mapping rules are not sufficient, explicit mapping rules can be registered by calling one of the mapper.addMapping(...) method variants. + When default mapping rules are not sufficient, explicit mapping rules can be registered by obtaining a MapperBuilder and using it to construct a Mapper. Explicit mapping rules always override the default. - For example, suppose you need to map AccountDto.name to Account.fullName. - Since the two property names are not the same, default auto-mapping would never be performed. - Handle a situation like this by explicitly registering a mapping rule: - - mapper.addMapping("name", "fullName"); - - In this example, the name field will be mapped to the fullName field when the mapper is executed. - No default mapping will be performed for name since an explicit mapping rule has been configured for this field. + builder = MappingFactory.mappingBuilder(PersonDto.class, Person.class)]]> + +
+ Mapping between two fields with different names + + Suppose you need to map AccountDto.name to Account.fullName. + Since the two property names are not the same, default auto-mapping would never be performed. + Handle a situation like this by explicitly registering a mapping rule: + + builder.addMapping("name", "fullName") + + In this example, the name field will be mapped to the fullName field when the mapper is executed. + No default mapping will be performed for name since an explicit mapping rule has been configured for this field. + +
Forcing Explicit Mappings You can require that all mapping rules must be defined explicitly by disabling the "auto mapping" feature: - mapper.setAutoMappingEnabled(false); + +
@@ -1623,12 +1634,13 @@ public void testDefaultSpelMappingBehavior() { Do this by registering a converter with a Mapping: () { +builder.addMapping("name", "fullName").setConverter() { new Converter() { public String convert(String value) { // do transformation // return transformed value } -});]]> +});]]> +
Ignoring Fields @@ -1636,21 +1648,21 @@ mapper.addMapping("name", "fullName").setConverter() { new Converter - mapper.addMapping("name").setExclude(); + builder.setExcludedFields("name");
Registering Custom Type Converters - You can also install Converters to convert values of different types in a custom way. - Do this by obtaining the mapper's ConverterRegistry: + You can also install Converters to convert values of different types in a custom way: () { +builder.addConverter(new Converter() { public Date convert(String value) { // do conversion // return transformed value } -});]]> +});]]> + The example Converter above will be invoked anytime a String field is mapped to a Date field. @@ -1662,55 +1674,18 @@ mapper.getConverterRegistry().addConverter(new Converter() { Do this by adding a nested Mapper: () { +builder.addNestedMapper(new Mapper() { public Address map(AddressDto source, Address target) { // do target bean mapping here return target; } -});]]> +});]]> + The example above registers a nested Mapper that will map nested AddressDto properties to nested Address properties. - This particular nested Mapper is "hand-coded", but it could have easily been another generic SpelMapper instance. - addNestedMapper is a convenience method for registering a Converter that delegates to a Mapper. + This particular nested Mapper is "hand-coded", but it could have easily been another Mapper instance built by a MapperBuilder.
-
- Registering Custom Mappable Types - - By default, SpelMapper can map between JavaBean (Object), Collection, Array, and Map object structures. - The supported set of MappableTypes is extensible. - For example, you may wish to implement custom support for mapping XML element structures. - - - To implement your own custom MappableType, implement the MappableType interface: - - { - - boolean isInstance(Object object); - - Set getFields(T object); - - EvaluationContext getEvaluationContext(T object, ConversionService conversionService); - -}]]> - - To plug in your custom MappableType, inject a custom MappableTypeFactory into your SpelMapper: - - - - - The Spring team encourages you to contribute any generally useful MappableType extensions back to the community. - Do this by filing a JIRA issue at jira.springframework.org. - - -
Further Reading