Marshalling and Unmarshalling Java Objects using JAXB

By ongraph | December 9, 2013 | 6064 Views
JAVAXB – Marshling/UnMarshaling (Convert Object <—> Xml)

 

JAXB :

Java for XML Binding, Use annotation pattern to convert java object to or from xml. Here the two terms mostly used are Marshaling and Unmarshaling.

 

Marshaling :

By use of java object create xml file or convert java object ot xml.

UnMarshaling :

Create java object again using xml file.

Prerequisitions :

  • JDK 1.6
  • JAXB 2
Note : If using jdk version less than 1.6, download JAXB from http://jaxb.java.net/, and copy “jaxb-api.jar” and “jaxb-impl.jar” and paste to your classpath. No extra jaxb libraries are required if you are using JDK1.6 or above because it is bundled with jdk

 

JAXB Annotation :

To convert object to/from xml JAXB, use Annotation pattern. There are various types of predefined annotation patterns that we can use to annotate our java objects. This annotation does not take part directly in xml creation rather it provide information about xml schema. It has several attributes like factoryClass, factoryMethod, name, namespace, propOrder etc.

Below are some commonly used attributes –

name – Provides name to XML schema if you don't want to use the class name

namespace – Provides the name of the target namespace (if you are using reference object of some other class)

propOrder – Used to establishes an ordering of the sub-elements

  

@XmlRootElement(name="TestDoc" )
@XmlType(propOrder = { "name", "stream", "class"})
public class TestingDocument
{
	String name;
	int class;
	String stream;
	
	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 String getStream() {
		return stream;
	}
 
	@XmlElement(name = "subject")
	public void setStream(String stream) {
		this.stream = stream;
	}	
}

According to TestingDocument class order of properties is name > class > stream but as we have defined new ordering in @XmlType annotation so it will produce output xml like –
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<TestDoc>
    <age></age>
    <subject></subject>
    <name></name>
</TestDoc>

The basic annotation for a field that's intended to be an element is XmlElement. It permits you to define the XML element name and namespace.
In above example, property stream is reanamed by subject using name property of XMLElement annotation.
  • @XmlRootElement (name = “root”) :
    Top level element class, Define root element of xml document. Its optional elements are name and namespace. By default we used class name as the name.

    @XmlRootElement(name="TestDoc" )
    public class TestingDocument
    {
    }
    After Marshaling of this java class, It will produced out put xml like –
    <?xml version="1.0" encoding="UTF-8"?><TestDoc>
    </TestDoc>

  • @XmlType(propOrder = { “field2”, “field1”,”field3″….}) :
  • @XmlElement(name = “test”)

 

Here is one more condition that I would like to explain here. Sometimes you need to define property with xml tab like in below xml property subjectType in subject tag-

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<TestDoc>
    <age>25</age>
    <subject subjectType="Math" >Science</subject>
    <name>testinguser</name>
</TestDoc>

To handle this type condition, we need to create one more java class that will use to set have property subjectType and it's value, In our example we create a subject class like –

public class Subject {
	@XmlValue
	private String Subject;
	@XmlAttribute(name = "subjectType", required = true)
	private String subjectType;
			
	public String getSubject() {
		return StandardPrice;
	}	
	
	public void setSubject(String value) {
		StandardPrice = value;
	}

	public void setSubjectType(String currency) {
		this.currency = currency;
	}	
	
	public String getSubjectType() {
		return currency;
	}			
}

And TestingDocument's setStream() method now set the object reference of subject class

@XmlRootElement(name="TestDoc" )
@XmlType(propOrder = { "name", "stream", "class"})
public class TestingDocument
{
	String name;
	int class;
	Subject stream;
	
	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 Subject getStream() {
		return stream;
	}
 
	@XmlElement(name = "subject")
	public void setStream(Subject stream) {
		this.stream = stream;
	}	
}

In above code we used @XmlValue to denote that this is used to add property value not a new xml tag. If we do not define this, then it will produce one extra <subject> tag with in a main <subject> tag. @XmlAttribute(name = “subjectType”, required = true) here we are defining that property name will be subjectType and it is a required field. Method getSubjectType() will return the value of subjectType property and getSubject() method will return the value of subject tag in XML.
 
If you want to wrap multiple tags with in a parent tag for example –
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<students>
    <student></student>
	<student></student>
	<student></student>
</students>

To implement this type of condition, create class student and students and in students class, create a property having ArrayList of type student class.
 

JAXB marshalling example :

package com.tst.javaxb;
 
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
 
public class TestingDocumentExample {
	public static void main(String[] args) {
 
	  TestingDocument testDoc = new TestingDocument();
	  testDoc.setName("testuser");
	  testDoc.setAge(25);
	  Subject sub = new Subject();
	  sub.setSubject("Science");
	  sub.setSubjectType("Meth");
	  testDoc.setStream(sub);
 
	  try { 
		File file = new File("C:\\file.xml");
		JAXBContext jaxbContext = JAXBContext.newInstance(TestingDocument.class);
		Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
 
		// output pretty printed
		jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
 
		jaxbMarshaller.marshal(testDoc, file);
		//to show out put in console
		jaxbMarshaller.marshal(testDoc, System.out);
 
	      } catch (JAXBException e) {
		e.printStackTrace();
	      }
	}
}

JAXB unmarshalling example :

package com.tst.javaxb;
 
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
 
public class TestingDocumentExampleUnMarshal {
	public static void main(String[] args) {
	 try {
		File file = new File("C:\\file.xml");
		JAXBContext jaxbContext = JAXBContext.newInstance(TestingDocument.class);
 
		Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
		TestingDocument tstDoc = (TestingDocument) jaxbUnmarshaller.unmarshal(file);
		System.out.println(tstDoc);
	  } catch (JAXBException e) {
		e.printStackTrace();
	  }
     }
}

References:

 

About the author

ongraph

Monthly industry insights to keep you updated on latest happenings

Follow us on Twitter
Follow us on Facebook
Follow us on Linkedin