Suppose I have the following classes:
class A1 {
List<B1> bList;
}
class B1 {
Long id;
}
---
class A2 {
List<Long> bList;
}
I want to map class A1 to A2 with Dozer, where A1.bList contains B1 objects and A2.bList contains only the IDs of the B1 objects.
How woul开发者_开发技巧d the mapping look like?
Thank you.
I think you could try setting up a mapping for Long
to B1
. If I remember rightly this only works one way, I can't remember which way tho. Sorry, hope this helps.
You can use a dozer custom converter. Dozer customer converter
An example: (possible errors, didn't compile or test it)
<mapping>
<class-a>A1</class-a>
<class-b>A2</class-b>
<field custom-converter="converters.YourCustomConverter">
<a>bList</a>
<b>bList</b>
</field>
</mapping>
The custom converter:
public class YourCustomConverter implements CustomConverter {
public Object convert(Object destination, Object source, Class destClass, Class sourceClass) {
if (source == null) {
return null;
}
if (source instanceof List<?>) {
List<?> list = ((List<?>) source);
if (list.isEmpty()) {
return null;
}
if (list.get(0) instanceof B1) {
List<Long> longList = new ArrayList<Long>();
for (B1 b1 : list) {
longList.add(b1.getId());
}
return longList;
} else (list.get(0) instanceof Long) {
// do the inverse of the above
} else {
throw new MappingException("Wrong type ...");
}
} else {
throw new MappingException("Converter YourCustomConverter used incorrectly. Arguments passed in were:"
+ destination + " and " + source);
}
}
}
I think you can do this by overridding toString() method in B1 and it would work.
Here's sample code:
@Override
public String toString() {
return new String(this.id);
}
And in your mapping do the following changes:
<field>
<a>bList</a>
<b>bList</b>
<a-hint>B</a-hint>
<b-hint>java.lang.Long<b-hint>
</field>
So,when dozer tries to bind B1, it will return its id as String and then dozer will perform an automatic conversion between String and Long.
精彩评论