Marshalling and Unmarshalling Java Objects using JAXB

Java API for XML Binding (JAXB) is an acronym that stands for Java Architecture for XML Binding. It enables you to write Java objects into XML and read them back as objects. Simply said, it allows you to convert Java objects into XML and vice-versa.

JAXB was designed to simplify the process of connecting Java programs with XML data and processing functions. JAXB makes it simple for Java developers to include XML data and processing operations in their applications by allowing them to bind XML schemas to Java representations. Unmarshalling (reading) XML instance documents into Java content is handled by JAXB, before marshalling (writing) Java content back into XML instance documents. JAXB also enables you to create XML schemas from java objects.

JAXB – Marshalling/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 using a java object, create an xml file or convert a java object to xml.

UnMarshaling :

Create a java object again using an xml file.

Prerequisites :

  • 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 :

JAXB Annotation
JAXB Annotation

To convert things to/from XML using JAXB, use the Annotation pattern. We can apply a number of predefined annotation styles to our Java objects. This annotation does not participate directly in the xml creation; rather, it supplies information about xml schema. It has various properties like factoryClass, method, name, namespace, propOrder, and so on.

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 a reference object of some other class)

propOrder – Used to establish 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 the above example, the property stream is renamed by subject using the name property of the 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 the 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 be used to set have property subjectType and its 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 Testing Documents set stream() 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 the above code we used @XmlValue to denote that this is used to add a property value, not a new xml tag. If we do not define this, then it will produce one extra <subject> tag within a main <subject> tag. @XmlAttribute(name = “subjectType”, required = true) here we are defining that property name as subjectType and it is a required field. Method getSubjectType() will return the value of subjectType property and getSubject() method will return the value of the subject tag in XML.

If you want to wrap multiple tags within 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:

Conclusion

We hope this tutorial helped you in some manner. You can share your thoughts in the comments down below. Need expert advice? Meet our team of specialists today!