JAXB Tutorial

Last modified on October 11th, 2014 by Joe.

This article is an introductory tutorial for JAXB. Some time back I wrote a tutorial introducing Java StAX and after reading that lot of friends asked to write on JAXB and so this article.

JAXB is an acronym of Java Architecture for XML Binding. JAXB provides API to access and process a XML document. We can read or write XML files using JAXB. Unlike SAX, DOM parsers to use JAXB the developer need not be aware of XML parsing techniques.

XML Schema

Schema is a definition file for a XML document. It maintains the rule/syntax for a XML document. An XML document need not always have a schema. But if it has one it should adhere to its specifications. While using JAXB XML schema is not a mandatory requirement. Process can start with java pojo classes. But it is convenient to have associated XML schema so that we can use a binding compiler and generate the java classes. That schema should be written using W3C XML Schema Language.

JAXB Implementation

JAXB API is a set of interfaces for which we have various implementations. As part of Metro there is a project for JAXB providing reference implementation. JSR 222 is developed by JCP for JAXB. Latest version of JAXB as of now is JAXB 2.2. As part of this artice I am using Metro’s JAXB reference implementation. To run the sample code associated, you should download jaxb implementation and the jar files to the classpath.

JAXB Binding

JAXB is middle man between XML document and java instances. Important step in using JAXB is creating java POJO classes. XML schema can be used by a JAXB binding compiler to generate java classes. Those generated java classes match the XML schema and they will be loaded at runtime in the application. If we don’t have the XML schema, then we can manually code the POJO classes and annotate with JAXB annotations. We can instantiate those classes then read or write to XML. XJC – com.sun.tools.xjc.XJCTask is the binding compiler provided by metro. The JAXB classes generated from an XML Schema are POJOs with the standard JAXB annotations. They are intended to be compatible with other JAXB implementations.



Unmarshal and Marshal in JAXB

Unmarshal is the process of binding the XML document using JAXB compiler and generating mapping java classes then constructing the instances with values available in XML document.

Marshal is the reverse process of it. First we construct the instances and then write a XML document using the constructed instances.

In both the cases, we need create POJO classes first. If we have the XML schema that can be used to generate those classes using a JAXB binding compiler. If the XML schema is not available, then we should manually code those POJOs. Only then we can do unmarshal or marshal in an application.

Marshaling and unmarshaling can be done with other sources. That means, the XML need not be in file form. It can be a InputStream object, a URL, a DOM node, SAXSource.

To Unmarshal

Create POJOs or bind the schema and generate the classes. Create a JAXBContext object. (javax.xml.bind.JAXBContext) Create an Unmarshaller object. (javax.xml.bind.Unmarshaller) Call the unmarshal method. Use the get methods available in schema-genearated classes to access the values.

To Marshal

Create POJOs or bind the schema and generate the classes. Create the content tree by using set methods. Create a JAXBContext object. (javax.xml.bind.JAXBContext) Create a Marshaller object. (javax.xml.bind.Marshaller) Call the marshal method to persist the created content tree as XML document.

JAXB Unmarshal Sample

Download JAXBSample and Run

You need to download JAXB reference implementation from metro and add jar files inside the lib folder to run this sample.

Following is build.xml for the sample code. You can see that XJC is used to compile XSD and generate java classes.

<?xml version="1.0" standalone="yes"?> <project basedir="." default="run"> <property name="jaxb.home" value="." /> <path id="classpath"> <pathelement path="src" /> <pathelement path="classes" /> <pathelement path="schemas" /> <fileset dir="${jaxb.home}" includes="lib/*.jar" /> </path> <taskdef name="xjc" classname="com.sun.tools.xjc.XJCTask"> <classpath refid="classpath" /> </taskdef> <!--compile Java source files--> <target name="compile" description="Compile all Java source files"> <echo message="Compiling the schema..." /> <mkdir dir="gen-src" /> <xjc schema="zoo.xsd" package="com.javapapers.xml.jaxb" destdir="gen-src"> <produces dir="gen-src/com.javapapers.xml.jaxb" includes="**/*.java" /> </xjc> <echo message="Compiling the java source files..." /> <mkdir dir="classes" /> <javac destdir="classes" debug="on"> <src path="src" /> <src path="gen-src" /> <classpath refid="classpath" /> </javac> </target> <target name="run" depends="compile" description="Run the sample app"> <echo message="Running the sample application..." /> <java classname="com.javapapers.xml.jaxb.JAXBUnmarshalSample" fork="true"> <classpath refid="classpath" /> </java> </target> <target name="javadoc" description="Generates javadoc" depends="compile"> <echo message="Generating javadoc..." /> <mkdir dir="docs/api" /> <javadoc sourcepath="gen-src" destdir="docs/api" windowtitle="Using unmarshaller (formerly SampleApp1)" useexternalfile="yes"> <fileset dir="." includes="gen-src/**/*.java" excludes="**/impl/**/*.java" /> </javadoc> </target> <target name="clean" description="Deletes all the generated artifacts."> <delete dir="docs/api" /> <delete dir="gen-src" /> <delete dir="schemas" /> <delete dir="classes" /> </target> </project>

Following the XSD

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="zoo" type="zooInfo"/> <xsd:element name="comment" type="xsd:string"/> <xsd:complexType name="zooInfo"> <xsd:sequence> <xsd:element name="zooName" type="xsd:string"/> <xsd:element name="zooId" type="xsd:int"/> <xsd:element name="animals" type="Animals"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="Animals"> <xsd:sequence> <xsd:element name="animal" minOccurs="1" maxOccurs="unbounded"> <xsd:complexType> <xsd:sequence> <xsd:element name="animalName" type="xsd:string"/> <xsd:element name="animalType" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:schema>

The XML document which we are going to read and print in console:

<?xml version="1.0"?> <zoo> <zooName>Vandalur Zoo</zooName> <zooId>12321</zooId> <animals> <animal> <animalName>Lion</animalName> <animalType>Wild</animalType> </animal> <animal> <animalName>Dog</animalName> <animalType>Domestic</animalType> </animal> <animal> <animalName>White Tiger</animalName> <animalType>Wild</animalType> </animal> </animals> </zoo>

Following is the java code to read the XML file

package com.javapapers.xml.jaxb; import java.io.FileInputStream; import java.io.IOException; import java.util.List; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; public class JAXBUnmarshalSample { public static void main(String[] args) { try { JAXBContext jaxbContext = JAXBContext .newInstance("com.javapapers.xml.jaxb"); Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); JAXBElement> zoo = (JAXBElement>) unmarshaller .unmarshal(new FileInputStream("zoo.xml")); ZooInfo zooInfo = (ZooInfo) zoo.getValue(); System.out.println("Zoo Name: " + zooInfo.getZooName()); System.out.println("Zoo Id: " + zooInfo.getZooId()); Animals animals = zooInfo.getAnimals(); List animalsList = animals.getAnimal(); for (Animals.Animal animal : animalsList) { System.out.println("\t" + animal.getAnimalName()); System.out.println("\t\t" + animal.getAnimalType()); } } catch (JAXBException je) { je.printStackTrace(); } catch (IOException ioe) { ioe.printStackTrace(); } } }

Output:

Zoo Name: Vandalur Zoo Zoo Id: 12321 Lion Wild Dog Domestic White Tiger Wild

JAXB Marshal Sample

After doing the above unmarshal we can use the same XSD and generated classes. Use the main method below to marshal.

package com.javapapers.xml.jaxb; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.util.List; import javax.xml.bind.JAXB; import javax.xml.bind.JAXBElement; public class JAXBMarshalSample { public static void main(String[] args) throws FileNotFoundException { ZooInfo zoo = new ZooInfo(); zoo.setZooId(987789); zoo.setZooName("Gir National Park"); Animals animals = new Animals(); List animalsList = animals.getAnimal(); Animals.Animal animal1 = new Animals.Animal(); animal1.setAnimalName("Jaguar"); animal1.setAnimalType("Wild"); Animals.Animal animal2 = new Animals.Animal(); animal2.setAnimalName("Goat"); animal2.setAnimalType("Domestic"); Animals.Animal animal3 = new Animals.Animal(); animal3.setAnimalName("Puma"); animal3.setAnimalType("Wild"); animalsList.add(animal1); animalsList.add(animal2); animalsList.add(animal3); zoo.setAnimals(animals); // create an element for marshalling JAXBElement zooInfoElement = (new ObjectFactory()).createZoo(zoo); // create a Marshaller and marshal to System.out JAXB.marshal(zooInfoElement, new FileOutputStream(new File("marshalledZoo.xml"))); } }

Download JAXBSample and Run

JAXB Advantages

JAXB is simple to use compared to SAX/DOM.

JAXB allows non-sequential processing of XML documents. In DOM we need to navigate a tree structure and JAXB doesn’t requires such navigations.

We work with java instances instead of event/elements.

JAXB uses memory efficiently than DOM.

JAXB uses memory efficiently than DOM. We can unmarshal XML data from different sources like InputStream object, a URL, a DOM node, or a transformed source object including a file.

Similarly we can marshal XMl content tree to different data targets.

Before closing some personal thoughts. I have written many starter articles touching subjects like Ajax, serialization, threading, web services, xml handling , java memory, design patterns and so on. When I take a subject I wish to write multiple articles on it covering major aspects of it. But it doesn’t happen always as I keep jumping between topics.

I have done well on covering design patterns. Java is like a ocean and every topic fascinates me and love to write on all those. Day by day javapapers is getting popular and we are adding new friends to the javapapers community. Added to appreciations I get lot of requests to write on certain topics.

Till now I have been predominantly writing on core java. This is to inform you friends I am planning to start writing Spring very soon and also expand to Hibernate and Android :-)