JAXB Tutorial

JAXB stands for Java Architecture for XML Bindings. In a nutshell, JAXB used for convert Java Object to XML and vice versa. We called it marshalling to convert Java object to XML and unmarshalling to convert XML to Java object. JAXB bundled in Java 1.6++, so we do not need another external libraries (but sometimes I loved to adding testing and logging framework). First, you have to know the technology that I used in this tutorial are :

  1. Maven 3
  2. TestNG (for unit test)
  3. commons-io

Some of you would frown and said “hmm, why you put commons-io on this tutorial?”. Simple, I used it in unit-test to get xml file from resource folder and convert to String, I know it can be done with the classic inputstream ways. but remember to not reinventing the wheel 🙂

First, let see the xml example :

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<human>
	<people id="1">
		<name></name>
		<age></age>
		<phone></phone>
		<addresses>
			<address>
				<street></street>
				<city></city>
			</address>
		</addresses>
	</people>
	<people id="2">
		<name></name>
		<age></age>
		<phone></phone>
		<addresses>
			<address>
				<street></street>
				<city></city>
			</address>
			<address>
				<street></street>
				<city></city>
			</address>
		</addresses>
	</people>
</human>

The xml above are example what xml will be. in JAXB, we can mapping every single element in xml into object, if we have many element with same type, just store in collection object like List. we will find several annotation, here are some brief explanations :

  1. @XmlRootElement : class that marked with this annotation will act as root/base element.
  2. @XmlElement : marked the property as element.
  3. @XmlAttribute : marked the property as attribute.
  4. @XmlType : used this annotation to specified xml element ordering.
  5. @XmlTransient : prevent the javabean property mapping to XML.
  6. @XmlElementWrapper : element wrapper for child element.

The important things from my example is, I made JAXB Context instance singleton,because remember marshalling and unmarshalling are expensive operation.

public class HumanFactory {

	private static JAXBContext humanFactory;

	public static synchronized JAXBContext getHumanContext() throws Exception {
		if (humanFactory == null) {
			humanFactory = JAXBContext.newInstance(
					Human.class);
		}
		return humanFactory;
	}

}

so when you want to do marshall or unmarshall, you just have to do like :

//for unmarshall
HumanFactory.getHumanContext().createUnmarshaller();

//for marshall
HumanFactory.getHumanContext().createMarshaller();

In every XML, we know root element, root element is like parent or base element from XML. In my example root xml is define in class Human.

package com.kusandriadi.jaxb.bean;

import java.util.ArrayList;
import java.util.List;

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

@XmlRootElement(name = "human")
public class Human {

	@XmlElement(required=true)
	private List<People> people = new ArrayList<People>();

	public List<People> getPeople() {
		return people;
	}

	/*
	 *  all methods below made for test purpose
	 */
	public Human addPeople(People people) {
		getPeople().add(people);
		return this;
	}
}

Example class above is very simple, we define @XmlRootElement to marked “human” as root. then we create a property collection of People.class with annotation @XmlElement and attribute required=true which means the xml must be contains one or many people element. it should clear from my explanation, now let’s go to the People.class, what is going on there 🙂

package com.kusandriadi.jaxb.bean;

import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;

@XmlRootElement(name="people")
@XmlType(propOrder = { "name", "age", "phone", "address"})
public class People {

	@XmlAttribute
	private String id;

	@XmlElement(required=true)
	private String name;

	@XmlElement
	private int age;

	@XmlElement(required=true)
	private String phone;

	@XmlElementWrapper(name = "addresses", required = true)
	private List<Address> address = new ArrayList<Address>();

	public People() {}

	public People(String id) {
		this.id = id;
	}

	public String getId() {
		return id;
	}

	@XmlTransient
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@XmlTransient
	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@XmlTransient
	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	@XmlTransient
	public List<Address> getAddress() {
		return address;
	}

	public void setAddress(List<Address> address) {
		this.address = address;
	}

//the rest of class here

 

wohoo, its look complicated? of course no, thats just how you look the class, in fact it is not too complicated. We found new annotation here, @XmlType with attribute propOrder will arrange the element ordering, if you want umarshalling xml with wrong ordering XML, simple, it would give us an error 🙂 @XmlTransient will prevent that property to map to Xml representation, why we dont want to transform that property? yes, because we have declared that property in Human.class

@XmlElement(required=true)
private List<People> people = new ArrayList<People>();

JAXB is smart enough to looking property has been declare as element or no. if so, then we have to add @XmlTransient to prevent collision. then with this example, we know when we declare @XmlElement, all property inside those class will mark as element or attribute. then we dont have to mark those property again. if you did, just mark as @XmlTransient.

I will not continue to Address.class, because you can look the code in my github repo below. it would give us some example as Human.class or People.class, if you already understand with implementation there, then you should ready to go.

anyway, You can get or clone the tutorial example here. thanks! 🙂

regards,

tandatangankecil

 

Leave a Reply

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