JAXB: XmlAdapter for List <Object> objects

Does anyone know how to bind a custom XmlAdapter to objects contained in a heterogeneous list (e.g. List)? For example, suppose we have a container class with a list of non-contiguous objects:

 @XmlRootElement(name = "container") public class Container { private List<Object> values = new ArrayList<Object>(); @XmlElement(name = "value") public List<Object> getValues() { return values; } public void setValues(List<Object> values) { this.values = values; } } 

If we put String -s, Integer -s, etc., they will be displayed by default. Now suppose we want to put a custom object:

 public class MyObject { //some properties go here } 

The obvious solution is to write a custom adapter:

 public class MyObjectAdapter extends XmlAdapter<String, MyObject> { //marshalling/unmarshalling } 

But, unfortunately, it does not work with the @XmlJavaTypeAdapter package - an adapter that has never been called, so marhalling fails. And I cannot apply it to getValues() directly, because there may be other types of objects. @XmlJavaTypeAdapter only works if I have a field of type MyObject in the container (also with package level annotate):

 public class Container { private MyObject myObject; } 

But this is not what I want - I need a list of arbitrary objects. I use the standard Sun JAXB implementation:

 <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId> <version>2.2.3-1</version> </dependency> 

Any ideas how to do the mapping?

PS: A little clarification - I would like to avoid annotating MyObject with JAXB annotations. This may be a class from a third-party library, which is not under my control. Therefore, any changes should be outside of MyObject .

+7
source share
1 answer

You can try changing MyObjectAdapter so that it extends XmlAdapter<String, List<Object>> . Therefore, it should look something like this:

 public class MyObjectAdapter extends XmlAdapter<String, List<Object>> { //marshalling/unmarshalling } 

When you also add the XmlJavaTypeAdapter annotation to the receiver in the Container class, it should work.

 @XmlRootElement(name = "container") public class Container { private ArrayList<Object> values = new ArrayList<Object>(); @XmlElement(name = "value") @XmlJavaTypeAdapter(MyObjectAdapter.class) public ArrayList<Object> getValues() { return values; } public void setValues(ArrayList<Object> values) { this.values = values; } } 
0
source

All Articles