Original URL: https://www.theregister.com/2006/09/22/jaxb2_guide/
A practical guide to JAXB 2.0
Take a peek at its new features
Posted in Software, 22nd September 2006 11:40 GMT
JSR222 specifies the Java Architecture for XML Binding (JAXB) 2.0. JAXB 2.0 specification is implemented in Java Web Services Developer Pack (JWSDP) 2.0. JAXB 2.0 has some new features that facilitate the marshalling and unmarshalling of an XML document. I have used both JAXB 1.0 and JAXB 2.0 and have found that JAXB 2.0 generates less code and has some additional features.
How is JAXB 2.0 better than JAXB 1.0?
- JAXB 2.0 uses parameterized types, a new feature in JDK 5.0. The advantage of parameterized types is compile time type checking. JAXB 2.0 also uses annotations. Annotations provide a metadata facility with which code may be generated using annotation types and annotation declarations.
- JAXB 2.0 supports all of XML Schema constructs, JAXB 1.0 doesn't.
- With JAXB 2.0 fewer Java classes are generated from an XML Schema as compared to JAXB 1.0. For each top level
complexType
, a value class is generated, instead of an interface and an implementation class. For each top-level element, a factory class method is generated, instead of an interface and an implementation class. - Fewer runtime libraries are required for JAXB 2.0.
- In JAXB 2.0, support for binding Java to XML has been added with
javax.xml.bind.annotation
package. - JAXB 2.0 provides integration with the Java API for XML-based Web Services (JAX-WS) 2.0.
Comparison of JAXB 2.0 with DOM and SAX
Both JAXB 2.0 and DOM APIs provide random access to the XML Infoset. In a performance comparison the DOM API as implemented in Apache Xerces was found to be 20 per cent faster than the JAXB 2.0 API. The SAX API has the advantage of being a event-based streaming API and is therefore less memory intensive. But, the SAX API does not offer random access of the XML Infoset. JAXB 2.0 combines the advantages of the random access processing model and the event based streaming processing model with unmarshal()
methods that unmarshal from an XMLStreamReader
or XMLEventReader
object.
Overview
In this article we shall discuss the new features of JAXB 2.0. We shall marshal and unmarshal an XML document with JAXB 2.0 API. Marshalling an XML document is creating an XML document using the Java classes generated by compiling an XML schema. Unmarshalling an XML document is creating a Java representation of an XML document, and subsequently retrieving element and attribute values in the XML document. An example XML schema, catalog.xsd (resources zip file), shall be compiled with JAXB 2.0 binding compiler. An example XML document, catalog.xml, shall be marshalled and unmarshalled using the Java classes generated from the XML Schema.
Preliminary Setup
Download JWSDP 2.0, which includes an implementation of JAXB 2.0. Install JWSDP 2.0 in the C:\Sun\jwsdp-2.0 directory, the default installation directory. JAXB 2.0 gets installed in the C:\Sun\jwsdp-2.0\jaxb directory. As JAXB 2.0 uses parameterized types, which is a JDK 5.0 feature, you will also need to install JDK 5.0.
Install the Eclipse IDE. Create a new project JAXB2
with File>New>Project. Next, create a Java package, com.register.jaxb
with File>New>Package. In the Java package create a Java class, JAXBMarshaller.java
, with File>New>Class.
Similarly, create Java classes JAXBUnMarshaller.java
and JavaToXML.java
. JAXBMarshaller.java
is used to marshal an XML document and JAXBUnMarshaller.java
is used to unmarshal an XML document. JavaToXML.java
is used to map a Java class consisting of Java-to-XML binding annotations to an XML document.
Copy the code from JAXBMarshaller.java
, JAXBUnMarshaller.java
and JavaToXML.java
(resources zip file) to the Eclipse project. Import catalog.xml to the JAXB2 project with File>Import. Create a gen_source
folder in the JAXB2 project with File>New>Folder and Import catalog.xsd to the gen_source
folder. Add the gen_source
folder to project build path by selecting Project Properties.
In the Properties frame select the Java Build Path. Select the Source tab and add the gen_source
folder with Add Folder. To compile and run JAXB 2.0 applications, we need some JAXB 2.0 JAR files in the Java Build Path. We also need to set JAXB2 project JRE to J2SE 5.0 JRE. JAXB2 project Java Build Path is as shown in Figure 1.
The directory structure of the JAXB2 project is shown in Figure 2.
Compiling an XML Schema
In this section, we will bind the catalog schema, catalog.xsd, to Java classes with the xjc
compiler. We shall configure xjc
as an external tool in Eclipse. Select Run>External Tools>External Tools. In the External Tools frame, right-click on the Program node and select New to create a new configuration as shown in Figure 3.
Also, set environment variables JAVA_HOME
and JAXB_HOME
in the external tool configuration for xjc
in the Environment tab, as shown in Figure 4.
Run xjc
compiler on the example schema, catalog.xsd. Select catalog.xsd file in the Package Explorer window and then Run>External Tools>XJC.
The output from the XJC compiler is shown in Figure 5.
Schema-derived classes get generated in the gen_source
folder, as shown in Figure 6.
Java classes and interfaces are generated in package generated
, by default. For each xsd:complexType
schema component, one value class gets generated, instead of an interface and an implementation class. For example, for catalogType
complexType
a Java value class CatalogType.java
gets generated. An ObjectFactory.java
class also gets generated. The factory class consists of create methods to create Java value class objects.
Unmarshalling an XML Document
In this section we shall unmarshal the example XML document, catalog.xml. In the JAXBUnMarshaller.java
class create a JAXBContext
object, which provides a JAXB context for implementing JAXB binding framework operations. A JAXBContext
object is initialised with a colon-separated list of Java package names, which consist of schema-derived classes and user annotated classes.
JAXBContext jaxbContext = JAXBContext.newInstance("generated");
Create an Unmarshaller
object, which is used to convert an XML document to a Java object.
Unmarshaller unMarshaller = jaxbContext.createUnmarshaller();
If the application were a JAXB 1.0 application, we would have set the Unmarshaller
to be validating using setValidating()
method. The setValidating()
method has been deprecated in JAXB 2.0. Schema validation in JAXB 2.0 is performed using JAXP 1.3 validation API. Create a SchemaFactory
object and create a Schema
object from the SchemaFactory
object. Set the schema on the Unmarshaller
object. Error handling in JAXB 2.0 is implemented using the ValidationEventHandler
interface. To add error handling to the example application, create a class CustomValidationEventHandler
that implements the ValidatonEventHandler
interface. Create a ValidationEventHandler
object and set the ValidationEventHandler
object on the Unmarshaller
object.
Unmarshal using the unmarshal()
method, which returns a parameterized JAXBElement
object. The parameter type is CatalogType
in the example application.
JAXBElement<CatalogType> catalogElement =(JAXBElement<CatalogType>) unMarshaller.unmarshal(xmlDocument);
Obtain a CatalogType
object from the JAXBElement
object.
CatalogType catalog=catalogElement.getValue();
Retrieve the journalTitle
and publisher
values. Obtain a parameterized list of parameter type JournalType
. Iterate over the List
object and obtain a parameterized list of parameter type ArticleType
for each of the JournalType
objects. Iterate over the parameterized list of parameter type ArticleType
and output values for edition
, title
and author
.
To run the JAXBUnMarshaller.java
application in the Eclipse project JAXB2, right-click on the JAXBUnMarshaller.java
application and select Run As>Run. Output generated by running the application in Eclipse is shown in Figure 7.
Marshalling an XML Document
In this section we shall marshal an XML document, catalog.xml. In the JAXBMarshaller.java
class create a JAXBContext
object with the procedure similar to the previous section. Create a Marshaller
object, which is used to marshal a Java object to an XML document.
Marshaller marshaller = jaxbContext.createMarshaller();
To produce formatted output, set the Marshaller
property jaxb.formatted.output
to true
.
marshaller.setProperty("jaxb.formatted.output",new Boolean(true));
Next, create a Java object representation of the XML document to be marshalled. Create an ObjectFactory
object, which is used to initialise the Java object
ObjectFactory factory = new ObjectFactory();
Create a CatalogType
object, which represents root element catalog
.
CatalogType catalog = factory.createCatalogType();
Set the journalTitle
and publisher
attributes of root element catalog
. Create a JournalType
object, which represents a journal
element. Get a list of parameter type JournalType
from the CatalogType
object and add the JournalType
object to the List
object.
JournalType journal = factory.createJournalType(); List<JournalType> journalList = catalog.getJournal(); journalList.add(journal);
Create an ArticleType
object, which represents an article element. Set the edition
, title
and author
values. Obtain a List
object of parameter type ArticleType
and add the ArticleType
object to the List
. Similarly, add another ArticleType
object to the Java object representation. Next, obtain a JAXBElement
object of parameter type CatalogType
using a factory object. A JAXBElement
object is a JAXB representation of an XML element.
JAXBElement<CatalogType> catalogElement=factory.createCatalog(catalog);
Marshal the Java object using the marshal()
method.
marshaller.marshal(catalogElement, new FileOutputStream(xmlDocument));
To run the JAXBMarshaller.java
application in Eclipse, right-click on the application node and select Run As>Run. File catalog.xml gets generated. Refresh the JAXB2 project with File>Refresh. The XML file catalog.xml gets added to the JAXB2 project.
Mapping Java to XML Using Annotations
JAXB 2.0 has added the provision to marshal a Java object to an XML document using annotations. The annotations are defined in the javax.xml.bind.annotation
package. In this section we shall generate an example XML document, catalog2.xml (resources zip file), from a Java object using JAXB 2.0 annotations. The corresponding schema representation is listed in catalog2.xsd (resources zip file).
To create the XML document, create an annotated class, Catalog.java
(resources zip file). Create root element of the XML document with @XmlRootElement
annotation. Create a complexType
using @XmlType
annotation.
@XmlRootElement @XmlType(name="", propOrder={"publisher", "edition", "title", "author"})
The annotation element name
is specified as an empty string, because the complexType
is defined within an element. The element order is specified using propOrder
annotation element. In the Catalog
class define constructors for the class, the different JavaBean properties (edition, title, author). Root element catalog
has an attribute journal
. Define the journal
attribute using @XmlAttribute
annotation.
@XmlAttribute public String journal;
Define getter and setter methods for the different properties and the journal
attribute. Add a Java class, Catalog.java
, to the JAXB2 project in Eclipse. The directory structure of the JAXB2 project with the Catalog.java
class is shown in Figure 8.
In the marshalling class JavaToXML.java
create a JAXBContext
using newInstance()
method with Catalog.class
as argument to the method. Create a Catalog
class object and set the values of elements and attributes. Marshal the Catalog
object with a Marshaller
object. Run the JavaToXML.java
class in Eclipse. The XML document gets created. Java classes may also be mapped to XML Schemas.®