The XmlAdapter Field example demonstrates how to use the XmlAdapter interface and the @XmlJavaTypeAdapter annotation to provide a custom mapping of XML content into and out of a HashMap (field) that uses an int as the key and a String as the value.
Interface XmlAdapter and annotation @XmlJavaTypeAdapter are used for special processing of data types during unmarshalling/marshalling. There are a variety of XML data types for which the representation does not map easily into Java (for example, xs:DateTime and xs:Duration), and Java types which do not map conveniently into XML representations, for example implementations of java.util.Collection (such as List) and java.util.Map (such as HashMap) or for non-JavaBean classes.
The XmlAdapter interface and the @XmlJavaTypeAdapter annotation are provided for cases such as these. This combination provides a portable mechanism for reading/writing XML content into and out of Java applications.
The XmlAdapter interface defines the methods for data reading/writing.
/* * ValueType - Java class that provides an XML representation * of the data. It is the object that is used for * marshalling and unmarshalling. * * BoundType - Java class that is used to process XML content. */ public abstract class XmlAdapter<ValueType,BoundType> { // Do-nothing constructor for the derived classes. protected XmlAdapter() {} // Convert a value type to a bound type. public abstract BoundType unmarshal(ValueType v); // Convert a bound type to a value type. public abstract ValueType marshal(BoundType v); }
You can use the @XmlJavaTypeAdapter annotation to associate a particular XmlAdapter implementation with a Target type, PACKAGE, FIELD, METHOD, TYPE, or PARAMETER.
The XmlAdapter Field example shows how to use an XmlAdapter for mapping XML content into and out of a (custom) HashMap. The HashMap object, basket, in class KitchenWorldBasket, uses a key of type int and a value of type String. These data types should be reflected in the XML content that is read and written, so the XML content should look like this.
<basket> <entry key="9027">glasstop stove in black</entry> <entry key="288">wooden spoon</entry> </basket>
The default schema generated for Java type HashMap does not reflect the desired format.
<xs:element name="basket"> <xs:complexType> <xs:sequence> <xs:element name="entry" minOccurs="0" maxOccurs="unbounded"> <xs:complexType> <xs:sequence> <xs:element name="key" minOccurs="0" type="xs:anyType"/> <xs:element name="value" minOccurs="0" type="xs:anyType"/> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element>
In the default HashMap schema, key and value are both elements and are of data type anyType. The XML content will look like this:
<basket> <entry> <key>9027</> <value>glasstop stove in black</> </entry> <entry> <key>288</> <value>wooden spoon</> </entry> </basket>
To resolve this issue, the example uses two Java classes, PurchaseList and PartEntry, that reflect the needed schema format for unmarshalling/marshalling the content. The XML schema generated for these classes is as follows:
<xs:complexType name="PurchaseListType"> <xs:sequence> <xs:element name="entry" type="partEntry" nillable="true" maxOccurs="unbounded" minOccurs="0"/> </xs:sequence> </xs:complexType> <xs:complexType name="partEntry"> <xs:simpleContent> <xs:extension base="xs:string"> <xs:attribute name="key" type="xs:int" use="required"/> </xs:extension> </xs:simpleContent> </xs:complexType>
Class AdapterPurchaseListToHashMap implements the XmlAdapter interface. In class KitchenWorldBasket, the @XmlJavaTypeAdapter annotation is used to pair AdapterPurchaseListToHashMap with field HashMap basket. This pairing will cause the marshal/unmarshal method of AdapterPurchaseListToHashMap to be called for any corresponding marshal/unmarshal action on KitchenWorldBasket.
Follow these instructions to build and run the XmlAdapter Field example on your Application Server instance using the NetBeans IDE.
In NetBeans IDE, select File->Open Project.
In the Open Project dialog, navigate to tut-install/javaeetutorial5/examples/jaxb/.
Select the j2s-xmlAdapter-field folder.
Select the Open as Main Project check box.
Click Open Project.
Right-click the j2s-xmlAdapter-field project and select Run.
To compile and run the XmlAdapter Field example using Ant, in a terminal window, go to the tut-install/javaeetutorial5/examples/jaxb/j2s-xmlAdapter-field/ directory and type the following:
ant runapp |