...
To explain how Dozer can be uses within Camel we'll use the following example of a simple Customer Support Service. The initial version of the Service defined a 'Customer' object used with a very flat structure.
Code Block |
---|
lang | java |
---|
title | Legacy Customer Service Class | lang | java |
---|
|
public class Customer {
private String firstName;
private String lastName;
private String street;
private String zip;
public Customer() {}
public Customer(String firstName, String lastName, String zip, String street) {
this.firstName = firstName;
this.lastName = lastName;
this.zip = zip;
this.street = street;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
... getters and setters for each field
|
In the next version it was decided to structure the data better in the model by moving the address data into its own type, with the resultin domain object ending up looking like
Code Block |
---|
lang | java |
---|
title | Next Gen Customer object | lang | java |
---|
|
public class Customer {
private String firstName;
private String lastName;
private Address address;
public Customer() {}
public Customer(String firstName, String lastName, Address address) {
this.firstName = firstName;
this.lastName = lastName;
this.address = address;
}
....
public class Address {
private String zipCode;
private String streetName;
public Address() {}
public Address(String zipCode, String streetName) {
this.zipCode = zipCode;
this.streetName = streetName;
}
|
...
Dozer's configuration is extremely flexible and many mapping scenarios are covered here. For our simple example, the configuration looks like the following.
Code Block |
---|
language | mapping.xml |
---|
lang | mapping.xml |
---|
langtitle | mapping.xml |
---|
|
<mappings xmlns="http://dozer.sourceforge.net" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://dozer.sourceforge.net http://dozer.sourceforge.net/schema/beanmapping.xsd">
<mapping>
<class-a>org.apache.camel.converter.dozer.service.Customer</class-a>
<class-b>org.apache.camel.converter.dozer.model.Customer</class-b>
<field>
<a>street</a>
<b>address.streetName</b>
</field>
<field>
<a>zip</a>
<b>address.zipCode</b>
</field>
</mapping>
</mappings>
|
...
Camel provides a simple mechanism to integrate Dozer Mappers with it's own powerful Type Conversion framework. Its configured by creating an instance of 'DozerTypeConverterLoader
' providing it the camel context and an optional Dozer mapper. If no mapper is supplied, Camel's registry will be searched for suitable instances. The loader will query the Dozer Mapper for the the types it converts and a register them with Camel's Conversionn type conversion framework to be handled by the mapper.
Info |
---|
|
The Camel Dozer type converter does not support having the same type conversion paris in different mapping ids (eg map-id) in Dozer. |
In Java it can be configured as follows:
Code Block |
---|
|
DozerBeanMapper mapper = new DozerBeanMapper(Arrays.asList(new String[]{"mapping.xml"}));
new DozerTypeConverterLoader(camelContext, mapper);
|
Or in Spring
Code Block |
---|
|
<!-- the registry will be scanndscanned and 'mapper' below will be found and installed -->
<bean id="dozerConverterLoader" class="org.apache.camel.converter.dozer.DozerTypeConverterLoader" />
<bean id="mapper" class="org.dozer.DozerBeanMapper">
<property name="mappingFiles">
<list>
<value>mapping.xml</value>
</list>
</property>
</bean>
|
Configuring in OSGi blueprint
Available as of Camel 2.12
When using Dozer with OSGi Blueprint then its works better by configuring Dozer using the org.apache.camel.converter.dozer.DozerBeanMapperConfiguration
instead of org.dozer.DozerBeanMapper
, as shown below:
Code Block |
---|
|
<bean id="dozerConverterLoader" class="org.apache.camel.converter.dozer.DozerTypeConverterLoader">
<argument index="0" ref="myCamel"/>
<argument index="1" ref="mapper"/>
</bean>
<bean id="mapper" class="org.apache.camel.converter.dozer.DozerBeanMapperDozerBeanMapperConfiguration">
<property name="mappingFiles">
<list>
<value>mapping.xml</value>
</list>
</property>
</bean>
<camelContext id="myCamel" xmlns="http://camel.apache.org/schema/blueprint">
...
</camelContext> |
Now, where necessary, Camel will use Dozer to do conversions; In our case between the new domain and legacy Customer types e.g.
Code Block |
---|
|
// given the following route
from("direct:legacy-service-in").bean(new CustomerProcessor());
// and a processor
public class CustomerProcessor {
public Customer processCustomer(org.apache.camel.converter.dozer.model.Customer customer) {
...
}
}
// service objects can be sent to the processor and automagically converted by Camel & Dozer
template.sendBody("direct:legacy-service-in",new org.apache.camel.converter.dozer.service.Customer("Bob", "Roberts", "12345", "1 Main st."));
|