Contents

XmlAdapter

Some Java classes are not well suited for use with JAXB and at first glance may seem "unmappable" - for example, classes that do not have a default no-arg constructor, or classes for which an XML representation cannot be automatically determined. Using JAXB's XmlAdapter, you can define define custom code to convert the unmappable class into something that JAXB can handle. Then, you can use the @XmlJavaTypeAdapter annotation to indicate that your adapter should be used when working with the unmappable class.

XmlAdapter uses the following terminology:

ValueType - The type that JAXB knows how to handle out of the box.

BoundType - The type that JAXB doesn't know how to handle. An adapter is written to allow this type to be used as an in-memory representation through the ValueType.

Here, the Currency cannot be automatically mapped with JAXB because it does not contain a no-argument constructor. However, we can write an adapter that will convert the Currency into something that JAXB does know how to handle - a simple String. Luckily, in this case the Currency's toString() method returns the currency code, which can also be used to create a new Currency:

Example - java.awt.Point

Sometimes the best way to handle an unmappable class is to write a "stand-in" class which can be mapped with JAXB, and convert between the two classes in the XmlAdapter. In this example, we want to use the Point class. Because of that class' getLocation() method (which JAXB will pickup automatically and map), an infinite loop will occurr during marshalling. Because we cannot change the Point class, we will write a new class, MyPoint, and use it in the adapter.

Specifying Package-Level Adapters

In the example above, we annotated both Point properties with the @XmlJavaTypeAdapter annotation. If you have many of these types of properties - for example, in other domain classes - it can be more convenient to specify the @XmlJavaTypeAdapters at the package level.

We could define both of the adapter classes in package-info.java, and then we would not have to annotate any further Currency or Point properties: