How to Map Java Types to XML
The XmlAdapter interface allows you to serialize any Java type to XML, by providing a XmlAdapter implementation that maps the arbitrary Java object to a JAXB supported object.
For example, the following class is not JAXB-compatible because it lacks the argument-less default constructor and its fields are final:
public class EMailAddress { // not JAXB-compatible
public final String user, hostname;
public EMailAddress(String user, String hostname) {
this.user = user;
this.hostname = hostname;
}
}
The first step for mapping the EMailAddress class to XML is creating or finding a suitable JAXB-compatible type that can represent it. So let's define a bean XmlEMailAddress that can be serialized by JAXB:
public class XmlEMailAddress { // JAXB-compatible
public String user;
public String hostname;
}
The next step is to implement the XmlAdapter and provide methods to convert between EMailAddress and XmlEMailAddress:
public class XmlEMailAddressAdapter extends XmlAdapter<XmlEMailAddress, EMailAddress> {
@Override
public XmlEMailAddress marshal(EMailAddress v) {
XmlEMailAddress a = new XmlEMailAddress();
a.user = v.user;
a.hostname = v.hostname;
return a;
}
@Override
public EMailAddress unmarshal(XmlEMailAddress v){
return new EMailAddress(v.user, v.hostname);
}
}
Now you only need to declare that the XmlAdapter should be used for EMailAddress. For this you need the XmlJavaTypeAdapter annotation. It can be used at a property-level (to define the adapter only for this property or field), at the mapped class, or at the package level to define an adapter for the whole package. In this example, a class EMail is defined that uses the adapter only for a single property:
@XmlRootElement
public class EMail {
@XmlJavaTypeAdapter(value=XmlEMailAddressAdapter.class)
public EMailAddress recipient;
public String body;
}
Now EMail can be used like any other class:
EMail mail = new EMail();
mail.recipient = new EMailAddress("recipient", "example.com");
mail.body = "Hello!";
JAXB.marshal(mail, System.out);
This is the output of the last code fragment:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<eMail>
<recipient>
<user>recipient</user>
<hostname>example.com</hostname>
</recipient>
<body>Hello!</body>
</eMail>
An adapter can also map to a simple type such as a string. The following example shows an adapter that converts the EMail class into a string with the usual email notation:
public class XmlEMailAddressAdapter extends XmlAdapter<String, EMailAddress> {
@Override
public String marshal(EMailAddress v) throws Exception {
return v.user + "@" + v.hostname;
}
@Override
public EMailAddress unmarshal(String v) throws Exception {
return new EMailAddress(v.replaceFirst("@.*$", ""), v.replaceFirst("^.*@", ""));
}
}
When this is used as XmlAdapter, the following XML will be generated:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<eMail>
<recipient>recipient@example.com</recipient>
<body>Hello!</body>
</eMail>

