Saturday, 30 August 2014

JAXB Tutorial for Java XML binding with annotations

JAXB

JAXB stands for JAVA Architecture for XML bindings. We will come to it in some time. Before that we need to understand a even basic concept - Serialization. Simply speaking Serialization is the process of turning an object in memory into a stream of bytes so that it can be transferred over a network or stored in a persistent storage.


There are various ways to serialize an object. For eg.

  1.  Serialization via XML. Convert the Object to XML transfer it and then convert it back to XML. 
  2. You can do the save via JSON (Javascript object notation).
  3. Or you can use the Serialization provided by Java i.e by making your class implement Serilizable interface.
In this post we will see how can we serialize/de-serialize Objects to and from xml.

Note : The verbs Marshal and Unmarshal are synonymous with Serialize and Deserialize. Specially in XML serialization you will hear the words   Marshal and Unmarshal very frequently.


Dependencies ??

If you are using JDK 6 or higher version you don't have to worry about any dependencies as JAXB comes bundled with it. If you are using a lower version that Java 6 then you can download the jars from here. Download and add “jaxb-api.jar” and “jaxb-impl.jar” on your project classpath.

 To the code....

First Create a model class file in package opensourceforgeeks.model. Lets call it Employee.java . Add the following code to it.
package opensourceforgeeks.model;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

/**
 * 
 * @author athakur
 *
 */

@XmlRootElement
public class Employee {

    private String name;
    private int age;
    private int id;
    
    public String getName() {
        return name;
    }
    
    @XmlElement
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    
    @XmlElement
    public void setAge(int age) {
        this.age = age;
    }
    public int getId() {
        return id;
    }
    
    @XmlAttribute
    public void setId(int id) {
        this.id = id;
    }
    
    @Override
    public String toString() {
        return "Employee [name=" + name + ", age=" + age + ", id=" + id + "]";
    }

}
 


Next lets create a class to test this out.  Create class JAXBTest.java under package opensourceforgeeks.test. Add the following code to it and run - 

package opensourceforgeeks.test;

import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import opensourceforgeeks.model.Employee; 
/**
 * 
 * @author athakur
 *
 */ 
 public class JAXBTest {

    public static void main(String args[]) {

        Employee employee = new Employee();
        employee.setName("Aniket");
        employee.setAge(23);
        employee.setId(101);

        try {

            File file = new File("C:\\Users\\athakur\\Desktop\\data.txt");
            JAXBContext jaxbContext = JAXBContext.newInstance(Employee.class);
            Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
            jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

            
            System.out.println("Serializing Data");
            //Serilization
            //put the xml in the file
            jaxbMarshaller.marshal(employee, file);
            //also print it on standard ouput
            jaxbMarshaller.marshal(employee, System.out);
            
            Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
            
            System.out.println("Deserializing Data");
            //Deserialization
            //read the xml to get the Object
            Employee newEmployee = (Employee) jaxbUnmarshaller.unmarshal(file);
            System.out.println(newEmployee);

        } catch (JAXBException e) {
            e.printStackTrace();
        }


    }

}
Your project structure should look like below - as per above conventions of-course. You are free to put the code anywhere you like :)


Output : 

On the standard output console you can see - 

Serializing Data
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<employee id="101">
    <age>23</age>
    <name>Aniket</name>
</employee>
Deserializing Data
Employee [name=Aniket, age=23, id=101]

You can also verify the data in the file whose path you have provided. XML should be generated in that file. It will have same XML as shown on standard output. For more details you can refer to the tutorial provided on the JAXB official site.

NOTE1 : In the model classes that you annotate you need to have default constructor (If you do not have any constructors Java compiler will put one default no arg constructor for you). If you do not provide default constructor you will get following exception -

JAXBException occurred : 1 counts of IllegalAnnotationExceptions.

NOTE2 :  If you get following exception - 
No message body writer has been found for response class
Make sure you are annotating root element with @XmlRootElement

Summary

Its quite self explanatory - the bindings and the conversion. Got the following diagram from the web that explains it in simplest way -



Related Links

No comments:

Post a Comment

t> UA-39527780-1 back to top