JAXB defines the basic mapping rules between XML and Java that all JAXB implementations must support. These are referred to as default bindings, and the schema compiler uses them by default. In addition, JAXB is flexible enough to allow custom bindings, though by passing in the "configuration" in the form of binding declarations to the binding compiler.
In Chapter 10, we discussed how JAX-RPC maps and marshalls XML to Java. The default binding defined by JAXB is identical to the mapping specified in JAX-RPC. In this section, we will discuss some commonly used additional details and mappings . We encourage you to refer to the JAXB specifications for syntactical details regarding XML-Java mappings.
In addition to the types defined by JAX-RPC (Chapter 10, Table 10.3a), JAXB addresses mapping for the types shown in Table 13.1.
XML type |
Java type |
---|---|
xsd:unsignedInt |
long |
xsd:unsignedShort |
int |
xsd:unsignedByte |
Short |
xsd:time |
java.util.Calendar |
xsd:date |
java.util.Calendar |
xsd:anySimpleType |
java.lang.String |
XML enumerations map to Java classes where the name of the class is the name of the enumeration and the package corresponds to the target namespace. This was discussed in Chapter 10 (see Table 10.3b). JAXB generates similar mappings, and the generated interface has a getValue and setValue method to access the underlying value. Listings 13.4a and 13.4b show a sample XML schema and its corresponding Java interface.
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="Day"> <xsd:simpleType > <xsd:restriction base="xsd:string"> <xsd:enumeration value="Saturday"></xsd:enumeration> <xsd:enumeration value="Sunday"></xsd:enumeration> <xsd:enumeration value="Monday"></xsd:enumeration> <xsd:enumeration value="Tuesday"></xsd:enumeration> <xsd:enumeration value="Wednesday"></xsd:enumeration> <xsd:enumeration value="Thursday"></xsd:enumeration> <xsd:enumeration value="Friday"></xsd:enumeration> </xsd:restriction> </xsd:simpleType> </xsd:element> </xsd:schema>
public interface Days extends javax.xml.bind.Element{ String getValue(); void setValue(String value);
typesafe enumeration is an important concept. Because Java was designed to avoid using the C/C++ type enumerations (enum), developers often define simple sets of primitive values:
public class Days{ public static final int MONDAY= "Monday"; public static final int TUESDAY= "Tuesday"; public static final int WEDNESDAY= "Wednesday"; // And so on }
The problem with using Strings is that it causes numerous string comparisons and embeds the values in the code. The typesafe enum pattern takes the approach of using static final primitives one step further and essentially replaces the primitive constants with a set of static final object references encapsulated in a class:
public final class Days { public static final Days MONDAY = new Days(); public static final Days TUESDAY = new Days(); public static final Days WEDNESDAY = new Days(); // And so on private Daya() {} }
The static fields will be initialized when the class is loaded. Because the only way to construct the objects is internal to the class, there can be no other instance of these Days objects. Because the fields are final, the identity comparison (==) can be easily used instead of the equals() method—for example, if(someday== Days.TUESDAY) {}. This is analogous to comparing pointers in C/C++.
JAXB allows developers to specify that code generated for the enumerations in the schema use this typesafe enumeration pattern. By default, only XML enumerations derived by restriction from the base type "xsd:NCName" are mapped to typesafe enumeration classes.
XML lists map to java.util.List instances. The data types contained in the collection are either the Java mappings of the basic data types or objects based on the enumeration mapping. For example, consider this schema fragment:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="Catalog"> <xsd:simpleType> <xsd:list itemType="xsd:string"/> </xsd:simpleType> </xsd:element> </xsd:schema>
The element would map to a Catalog class object, and the getValue() would return a List of String objects:
public interface Catalog extends javax.xml.bind.Element{ java.util.List getValue(); }
If the itemType in the schema were an enumeration or a complex type, the List would contain the corresponding Java classes—for example, a List of Billingaddress objects.
As in JAX-RPC, XML complex types are mapped to Java interfaces. For example, Listings 13.5a and 13.5b show how the billingaddress element is mapped to Java.
package com.flutebank.schema; public interface Billingaddress extends javax.xml.bind.Element, com.flutebank.schema.BillingaddressType{ } package com.flutebank.schema; public interface BillingaddressType { com.flutebank.schema.Name getName(); void setName(com.flutebank.schema.Name value); com.flutebank.schema.Zip getZip(); void setZip(com.flutebank.schema.Zip value); com.flutebank.schema.State getState(); void setState(com.flutebank.schema.State value); com.flutebank.schema.City getCity(); void setCity(com.flutebank.schema.City value); com.flutebank.schema.Street getStreet(); void setStreet(com.flutebank.schema.Street value); }
Although the JAXB and JAX-RPC API were developed independently, and JAXB was released after JAX-RPC, both specify XML-to-Java and Java-to-XML mappings. We looked at the JAX-RPC mappings in Chapter 10. JAXB concentrates on the binding issue and therefore seeks to solve the larger problem of how XML and Java can work seamlessly through the use of compile-time bindings. Therefore, the treatment in JAXB is much more detailed and thorough. This should not be construed to mean that there are two sets of bindings. The bindings defined by JAX-RPC and discussed in Chapter 10 can be considered a subset of details addressed in JAXB. JAXB also allows for customization using the binding declaration mechanism.