JAXB – Java API for XML Binding

XML Binding

  • XML binding maps XML to objects
  • It generates Classes to represent XML elements. Classes follow JavaBean property access conventions.
  • Supports three principal operations. Marshalling – it marshalls a tree of objects into XML document. Unmarshalling – it unmarshalls an XMl document into a tree of objects. It also validates XML against the schema used to generate classes of objects. Validation of object trees against the schema used to generate classes.

XML Binding Relationships

Why use XML Bindings

  • We do not need to write much code while we have to if we use SAX or DOM
  • We do not need to learn SAX or DOM parser
  • It is less error prone because we do not have to manually implement them and all features of schema are utilized
  • It allows us to customize the XML structure

JAXB Use Cases

  • It is used to create, read or modify XML using Java but without using SAX or DOM parser
  • Using rules defined in XML schema it can validate user input

Now I will show you step by step how we can use JAXB to marshall and unmarshall XMl document easily.

Prerequisites

Eclipse 3.x, JDK 1.6, Maven 2.x, XSD

Step 1. Create a maven project in Eclipse with the below information

Group Id: in.webtuts
Artifact Id: jaxb

Step 2. Modify the pom.xml file to use jar libraries and to generate JAXB classes

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>in.webtuts</groupId>
	<artifactId>jaxb</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>jaxb</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>

	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.11</version>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<finalName>jaxb</finalName>
		<pluginManagement>
			<plugins>
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-compiler-plugin</artifactId>
					<configuration>
						<source>1.6</source>
						<target>1.6</target>
					</configuration>
				</plugin>
			</plugins>
		</pluginManagement>
		<plugins>
			<!-- JAXB xjc plugin that invokes the xjc compiler to compile XML schema 
				into Java classes. -->
			<plugin>
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>jaxb2-maven-plugin</artifactId>
				<version>1.6</version>
				<executions>
					<execution>
						<id>xjc</id>
						<goals>
							<goal>xjc</goal>
						</goals>
					</execution>
				</executions>
				<configuration>
					<!-- The schema directory or xsd files. -->
					<schemaDirectory>${project.basedir}/src/main/resources/xsd</schemaDirectory>
					<!-- The package in which the java source files will be generated. -->
					<packageName>in.webtuts.jaxb</packageName>
					<!-- The working directory to create the generated java source files. -->
					<outputDirectory>${project.basedir}/src/main/java</outputDirectory>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

Step 3. Put XSD file under src/main/resources/xsd folder. You can use the below sample XSD

<xs:schema attributeFormDefault="unqualified"
	elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
	<xs:element name="Catalog">
		<xs:complexType>
			<xs:sequence>
				<xs:element name="Book" maxOccurs="unbounded" minOccurs="0">
					<xs:complexType>
						<xs:sequence>
							<xs:element type="xs:string" name="Author" />
							<xs:element type="xs:string" name="Title" />
							<xs:element type="xs:string" name="Genre" />
							<xs:element type="xs:float" name="Price" />
							<xs:element type="xs:date" name="PublishDate" />
							<xs:element type="xs:string" name="Description" />
						</xs:sequence>
						<xs:attribute type="xs:string" name="id" use="optional" />
					</xs:complexType>
				</xs:element>
			</xs:sequence>
		</xs:complexType>
	</xs:element>
</xs:schema>

Step 4. Now open command prompt and navigate to the project location <project workspace>\jaxb. Execute the below command to build the project

mvn clean compile install

If build is successful, you will get BUILD SUCCESSFUL message and you will see the below classes generated in the folder src/main/java under package – in.webtuts.jaxb.

Catalog.java

//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.7 
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
// Any modifications to this file will be lost upon recompilation of the source schema. 
// Generated on: 2014.11.25 at 11:54:37 AM IST 
//


package in.webtuts.jaxb;

import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlType;
import javax.xml.datatype.XMLGregorianCalendar;


/**
 * <p>Java class for anonymous complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType>
 *   &lt;complexContent>
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       &lt;sequence>
 *         &lt;element name="Book" maxOccurs="unbounded" minOccurs="0">
 *           &lt;complexType>
 *             &lt;complexContent>
 *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *                 &lt;sequence>
 *                   &lt;element name="Author" type="{http://www.w3.org/2001/XMLSchema}string"/>
 *                   &lt;element name="Title" type="{http://www.w3.org/2001/XMLSchema}string"/>
 *                   &lt;element name="Genre" type="{http://www.w3.org/2001/XMLSchema}string"/>
 *                   &lt;element name="Price" type="{http://www.w3.org/2001/XMLSchema}float"/>
 *                   &lt;element name="PublishDate" type="{http://www.w3.org/2001/XMLSchema}date"/>
 *                   &lt;element name="Description" type="{http://www.w3.org/2001/XMLSchema}string"/>
 *                 &lt;/sequence>
 *                 &lt;attribute name="id" type="{http://www.w3.org/2001/XMLSchema}string" />
 *               &lt;/restriction>
 *             &lt;/complexContent>
 *           &lt;/complexType>
 *         &lt;/element>
 *       &lt;/sequence>
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/complexType>
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "book"
})
@XmlRootElement(name = "Catalog")
public class Catalog {

    @XmlElement(name = "Book")
    protected List<Catalog.Book> book;

    /**
     * Gets the value of the book property.
     * 
     * <p>
     * This accessor method returns a reference to the live list,
     * not a snapshot. Therefore any modification you make to the
     * returned list will be present inside the JAXB object.
     * This is why there is not a <CODE>set</CODE> method for the book property.
     * 
     * <p>
     * For example, to add a new item, do as follows:
     * <pre>
     *    getBook().add(newItem);
     * </pre>
     * 
     * 
     * <p>
     * Objects of the following type(s) are allowed in the list
     * {@link Catalog.Book }
     * 
     * 
     */
    public List<Catalog.Book> getBook() {
        if (book == null) {
            book = new ArrayList<Catalog.Book>();
        }
        return this.book;
    }


    /**
     * <p>Java class for anonymous complex type.
     * 
     * <p>The following schema fragment specifies the expected content contained within this class.
     * 
     * <pre>
     * &lt;complexType>
     *   &lt;complexContent>
     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
     *       &lt;sequence>
     *         &lt;element name="Author" type="{http://www.w3.org/2001/XMLSchema}string"/>
     *         &lt;element name="Title" type="{http://www.w3.org/2001/XMLSchema}string"/>
     *         &lt;element name="Genre" type="{http://www.w3.org/2001/XMLSchema}string"/>
     *         &lt;element name="Price" type="{http://www.w3.org/2001/XMLSchema}float"/>
     *         &lt;element name="PublishDate" type="{http://www.w3.org/2001/XMLSchema}date"/>
     *         &lt;element name="Description" type="{http://www.w3.org/2001/XMLSchema}string"/>
     *       &lt;/sequence>
     *       &lt;attribute name="id" type="{http://www.w3.org/2001/XMLSchema}string" />
     *     &lt;/restriction>
     *   &lt;/complexContent>
     * &lt;/complexType>
     * </pre>
     * 
     * 
     */
    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "", propOrder = {
        "author",
        "title",
        "genre",
        "price",
        "publishDate",
        "description"
    })
    public static class Book {

        @XmlElement(name = "Author", required = true)
        protected String author;
        @XmlElement(name = "Title", required = true)
        protected String title;
        @XmlElement(name = "Genre", required = true)
        protected String genre;
        @XmlElement(name = "Price")
        protected float price;
        @XmlElement(name = "PublishDate", required = true)
        @XmlSchemaType(name = "date")
        protected XMLGregorianCalendar publishDate;
        @XmlElement(name = "Description", required = true)
        protected String description;
        @XmlAttribute(name = "id")
        protected String id;

        /**
         * Gets the value of the author property.
         * 
         * @return
         *     possible object is
         *     {@link String }
         *     
         */
        public String getAuthor() {
            return author;
        }

        /**
         * Sets the value of the author property.
         * 
         * @param value
         *     allowed object is
         *     {@link String }
         *     
         */
        public void setAuthor(String value) {
            this.author = value;
        }

        /**
         * Gets the value of the title property.
         * 
         * @return
         *     possible object is
         *     {@link String }
         *     
         */
        public String getTitle() {
            return title;
        }

        /**
         * Sets the value of the title property.
         * 
         * @param value
         *     allowed object is
         *     {@link String }
         *     
         */
        public void setTitle(String value) {
            this.title = value;
        }

        /**
         * Gets the value of the genre property.
         * 
         * @return
         *     possible object is
         *     {@link String }
         *     
         */
        public String getGenre() {
            return genre;
        }

        /**
         * Sets the value of the genre property.
         * 
         * @param value
         *     allowed object is
         *     {@link String }
         *     
         */
        public void setGenre(String value) {
            this.genre = value;
        }

        /**
         * Gets the value of the price property.
         * 
         */
        public float getPrice() {
            return price;
        }

        /**
         * Sets the value of the price property.
         * 
         */
        public void setPrice(float value) {
            this.price = value;
        }

        /**
         * Gets the value of the publishDate property.
         * 
         * @return
         *     possible object is
         *     {@link XMLGregorianCalendar }
         *     
         */
        public XMLGregorianCalendar getPublishDate() {
            return publishDate;
        }

        /**
         * Sets the value of the publishDate property.
         * 
         * @param value
         *     allowed object is
         *     {@link XMLGregorianCalendar }
         *     
         */
        public void setPublishDate(XMLGregorianCalendar value) {
            this.publishDate = value;
        }

        /**
         * Gets the value of the description property.
         * 
         * @return
         *     possible object is
         *     {@link String }
         *     
         */
        public String getDescription() {
            return description;
        }

        /**
         * Sets the value of the description property.
         * 
         * @param value
         *     allowed object is
         *     {@link String }
         *     
         */
        public void setDescription(String value) {
            this.description = value;
        }

        /**
         * Gets the value of the id property.
         * 
         * @return
         *     possible object is
         *     {@link String }
         *     
         */
        public String getId() {
            return id;
        }

        /**
         * Sets the value of the id property.
         * 
         * @param value
         *     allowed object is
         *     {@link String }
         *     
         */
        public void setId(String value) {
            this.id = value;
        }

    }

}

ObjectFactory.java

//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.7 
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
// Any modifications to this file will be lost upon recompilation of the source schema. 
// Generated on: 2014.11.25 at 11:54:37 AM IST 
//


package in.webtuts.jaxb;

import javax.xml.bind.annotation.XmlRegistry;


/**
 * This object contains factory methods for each 
 * Java content interface and Java element interface 
 * generated in the in.webtuts.jaxb package. 
 * <p>An ObjectFactory allows you to programatically 
 * construct new instances of the Java representation 
 * for XML content. The Java representation of XML 
 * content can consist of schema derived interfaces 
 * and classes representing the binding of schema 
 * type definitions, element declarations and model 
 * groups.  Factory methods for each of these are 
 * provided in this class.
 * 
 */
@XmlRegistry
public class ObjectFactory {


    /**
     * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: in.webtuts.jaxb
     * 
     */
    public ObjectFactory() {
    }

    /**
     * Create an instance of {@link Catalog }
     * 
     */
    public Catalog createCatalog() {
        return new Catalog();
    }

    /**
     * Create an instance of {@link Catalog.Book }
     * 
     */
    public Catalog.Book createCatalogBook() {
        return new Catalog.Book();
    }

}

Step 5. Next is we need an XML document which validates against the above XSD. Below is the sample file. Put this XML file under src/main/resources/xml.

<?xml version="1.0"?>
<Catalog>
	<Book id="bk101">
		<Author>Garghentini, Davide</Author>
		<Title>XML Developer's Guide</Title>
		<Genre>Computer</Genre>
		<Price>44.95</Price>
		<PublishDate>2000-10-01</PublishDate>
		<Description>An in-depth look at creating applications
			with XML.</Description>
	</Book>
	<Book id="bk102">
		<Author>Garcia, Debra</Author>
		<Title>Midnight Rain</Title>
		<Genre>Fantasy</Genre>
		<Price>5.95</Price>
		<PublishDate>2000-12-16</PublishDate>
		<Description>A former architect battles corporate zombies,
			an evil sorceress, and her own childhood to become queen
			of the world.</Description>
	</Book>
</Catalog>

Step 6. Now we will create one test class which will marshall or unmarshall the above samle XMl file.

package in.webtuts.jaxb;

import in.webtuts.jaxb.Catalog.Book;

import java.io.File;
import java.util.Date;
import java.util.GregorianCalendar;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

public class MarshalUnmarshal {

  /**
   * @param args
   */
  public static void main(String[] args) {
    unmarshal();
    marshal();
  }

  private static void unmarshal() {
    try {
      JAXBContext jaxbContext = JAXBContext.newInstance(Catalog.class);
      Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
      Catalog catalogs = (Catalog) unmarshaller.unmarshal(new File("src/main/resources/xml/books.xml"));
      for (Book book : catalogs.getBook()) {
        System.out.println(book.getId());
        System.out.println(book.getTitle());
        System.out.println(book.getAuthor());
        System.out.println(book.getDescription());
        System.out.println(book.getGenre());
        System.out.println(book.getPrice());
        System.out.println(book.getPublishDate());
      }
    } catch (JAXBException e) {
      e.printStackTrace();
    }
  }

  private static void marshal() {
    try {
      JAXBContext jaxbContext = JAXBContext.newInstance(Catalog.class);
      Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

      jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

      Book book1 = new Book();
      Book book2 = new Book();

      GregorianCalendar gcalendar = new GregorianCalendar();
      gcalendar.setTime(new Date());
      XMLGregorianCalendar xmlDate = DatatypeFactory.newInstance().newXMLGregorianCalendar(gcalendar);

      book1.setId("1001");
      book1.setTitle("Title for Book One");
      book1.setAuthor("S Roy");
      book1.setDescription("Description of Book One");
      book1.setGenre("IT");
      book1.setPrice(450.0f);
      book1.setPublishDate(xmlDate);

      book2.setId("1002");
      book2.setTitle("Title for Book Two");
      book2.setAuthor("S Roy");
      book2.setDescription("Description of Book Two");
      book2.setGenre("CS");
      book2.setPrice(400.0f);
      book2.setPublishDate(xmlDate);

      Catalog catalog = new Catalog();
      catalog.getBook().add(book1);
      catalog.getBook().add(book2);

      //Marshal the books list in file
      jaxbMarshaller.marshal(catalog, new File("src/main/resources/xml/newbooks.xml"));
    } catch (JAXBException e) {
      e.printStackTrace();
    } catch (DatatypeConfigurationException e) {
      e.printStackTrace();
    }
  }

}

Step 7. Run the above test class and you will get output in the console.

bk101
XML Developer's Guide
Garghentini, Davide
An in-depth look at creating applications
			with XML.
Computer
44.95
2000-10-01
bk102
Midnight Rain
Garcia, Debra
A former architect battles corporate zombies,
			an evil sorceress, and her own childhood to become queen
			of the world.
Fantasy
5.95
2000-12-16

That’s all. Thank you for your reading.

Soumitra Roy Sarkar

I am a professional Web developer, Enterprise Application developer, Software Engineer and Blogger. Connect me on Roy Tutorials Twitter Facebook  Google Plus Linkedin Or Email Me

Leave a Reply

Your email address will not be published. Required fields are marked *