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