JAXBContext

The JAXB context initializes the underlying JAXB runtime with the appropriate factory information. The file named jaxb.properties is searched for in the classpath and the class indicated by the javax.xml.bind.context.factory property and is used to create the context. The context is passed the package name, which contains the binding information (multiple package names can be specified using the colon separator, ":"; this allows JAXB to manage the multiple schemas at one time). The packages specified must contain binding information generated by a single vendor (who provides the JAXB implementation). With multiple packages, the same context can be used to marshall and unmarshall multiple XML documents from different schemas in a single invocation. The JAXB implementation will ensure that each package on the context path has a jaxb.properties file containing a value for the javax.xml.bind.context.factory property and that all these values resolve to the same provider—in short, that the context is specific to a JAXB implementation. As mentioned earlier, the binding compiler generates the interfaces corresponding to schema constructs as well as the implementation for such interfaces. This raises the question of how multiple implementations can be used in a single app—for example, where an app component must be packaged and distributed and may potentially be used with other app components using another vendor's JAXB implementation. To facilitate such situations, different JAXB contexts would need to be created for different packages and possibly with different class loaders, using the alternate newInstance() method:

Unmarshaller

The javax.xml.bind.Unmarshaller is responsible for unmarshalling XML documents (which are based on the schema) into Java object representations. An Unmarshaller is created from a JAXBContext, using the createUnmarshaller() method:

The Java object representations that the XML is Unmarshalled into and Marshalled from are collectively called content trees. The tree represents a collection of object references defined by JAXB binding-compiler-generated interfaces.

Once created, the Unmarshaller can be applied to many different XML sources using convenient methods, as Table 13.3 shows.

Table 13.3: Unmarshalling from Different Sources

Unmarshalling method

Unmarshall from

public void Object umarshall(java.io.File f)

XML data from a file

public void Object unmarshall (org.xml.sax.InputSource source)

From the specified SAX InputSource

(See )

public void Object unmarshall (java.io.InputStream is)

From any InputStream

public Object unmarshall (org.w3c.dom.Node node)

From a W3C DOM tree

(See )

public void Object unmarshall (javax.xml.transform.Source source)

From the XML Source object.

(See )

public void Object unmarshall(java.net.URL url)

From a network URL

The Unmarshaller has two other important functions:

Performing validation during unmarshalling, to verify that the XML conforms to the schema. Upon invoking the setValidating(true), the Marshaller instance will be marked as a validating unmarshaller, and the JAXB provider performs XML validation against the schema used to generate the binding information:

JAXBContext context = JAXBContext.newInstance("com.flutebank.schema");
// create an Unmarshaller
Unmarshaller unmars = context.createUnmarshaller();
unmars.setValidating(true);
// Any XML instance unmarshalled will now be validated against the schema used by the
// binding compiler

Registering app-defined event handlers that are notified of validation events. Developers write the event handlers by implementing the javax.xml .bind.ValidationEventHandler method and registering this handler with the Unmarshaller, using the setEventHandler method:

The default validation handler in JAXB will terminate processing upon encountering the first fatal error. So if your app must recover gracefully or conditionally process the XML, consider overriding the default handler. This is analogous to the SAX handlers in .

Marshaller

The javax.xml.bind.Marshaller can be used to marshall object representations into XML format. The XML is based on the schema passed to the binding compiler and used to generate the initial Java bindings.

Much like the Unmarshaller, the Marshaller can marshal the Java object and its referenced objects (the content tree) into different destinations—files, DOM trees, and so on—summarized in Table 13.4.

Table 13.4: Marshalling Object Trees into Different Destinations

Marshalling method

Marshall the object and referenced objects therein into

public void marshall(Object obj, org.xml.sax.ContentHandler handler)

SAX2 events

public void marshall(Object obj, org.w3c.dom.Node node)

A DOM tree

public void marshall(Object obj, java.io.OutputStream os)

An output stream

public void marshall(Object obj, javax.xml.transform.Result result)

A javax.xml.transform.Result

Public void marshall(Object obj, java.io.Writer writer)

A Writer stream.

JAXB does not require that the Java content tree be valid or validated against the schema during the marshalling process to give the JAXB implementation the ability to support use cases where partial XML is generated. The provider may choose to disallow marshalling of invalid content and throw a MarshallException. As with the Unmarshaller, event handlers can be registered with the Marshaller using the setEventHandler(ValidationEventHandler handler) method. Even though there is no way to programmatically enable validation during the marshall operation, it is possible for validation events to be received by the handler. The default handler will stop the marshalling when the first fatal error is encountered.

Configuring the Marshaller

The Marshaller can be configured using four standard properties, described in Table 13.5, that affect the XML formatting and output. The properties are passed as name-value pairs using the setProperty method, as shown below.

Table 13.5: Marshaller Properties

Property

Description

jaxb.encoding

The Marshaller will use "UTF-8" by default. If needed the encoding can be changed using this property.

jaxb.formatted.output

By default the Marshaller will not format the output with line breaks and indentations. If this property is set to true the XML generated will be formatted for human readability.

jaxb.schemaLocation

Used to set the xsi:schemaLocation attribute in the generated XML. (See for details on this property.)

jaxb.noNamespaceSchemaLocation

Used to set the xsi:noNamespaceSchemaLocation property in the generated XML. (See for details on this property.)

The Element Interface

JAXB defines the javax.xml.bind.Element interface used by the runtime as a marker for identifying the JAXB-generated binding interfaces. It has no methods. In some situations, app developers would need to write code implementing this interface. JAXB users always work with the generated Java binding interface and its methods, which encapsulate the name and value of the corresponding XML element. For example, the billingaddress element is mapped to the Billingaddress interface, which has methods to get/set the relevant types, which themselves are generated bindings. This was shown in Listing 13.2. In XML schemas, the xsd:any element can be used to refer to elements not specified in the schema. For example, in the following fragment, the occupation element can be extended to include other content with the any element: