Wednesday, September 11, 2013

JAXB - using XmlAdapter class and @XmlJavaTypeAdapter annotation to write custom binding from java bean to xml

We can use JAXB to convert data between a xml and java bean. Using JAXB annotations like @XmlRootElement, @XmlAccessorType & @XmlElement we can achieve marshaling/unmarshaling of java bean to xml and vice versa.

Now sometime we come across problems where we need some custom conversion of an xml attribute to a java object.  When we are binding our own classes to XML, we are hit with a situation where our class representation doesn't match what we'd like to see in the XML.
In those cases, @XmlJavaTypeAdapter comes to our rescue. We can implement a custom java type adapter in the following way.

Identify the conversion from/ to

For example sake, we will be converting a java.lang.String to a custom GUID class (com.myorg.GUID)

Write custom adapter

public class StringToGUIDAdapter extends XmlAdapter<java.lang.String, GUID> {
@Override
public GUID unmarshal(String strGUID) throws Exception {
return new GUID(strGUID);
}
@Override
public String marshal(GUID guid) throws Exception {
if(null == guid)
return null;
else 
return guid.toString();
}
}

As you see, we have to extend XmlAdapter class and implement two of its methods - namely unmarshal & marshal.

Define the annotation in your java bean

Now you need to define your annotation @XmlJavaTypeAdapter on the java field like:-
  
  @XmlJavaTypeAdapter(type=String.class,value =StringToGUIDAdapter.class)
    private GUID                    entity;

And that is it. Your custom binding is ready to be used. 

@XmlJavaTypeAdapter annotation can be used with the following program elements:
  • a JavaBean property
  • field
  • parameter
  • package

This kind of custom binding is very useful when using JAX-RS and JSON.

1 comment: