Java Architecture for XML Binding (JAXB)3 min read

Even though JAXB is not a new technology, it is still useful when application information is contained within XML files. Starting with Java 1.6, JAXB was included with the Java Runtime Environment (JRE), so no additional libraries are required for its use if you are using newer Java versions. The benefit of using JAXB is directly converting XML into Java objects which can be used to obtain the information from the file. Conversely, you can create Java objects and write them to disk as XML. In JAXB, this is referred to as unmarshalling (reading XML) and marshalling (writing XML).

<?xml version="1.0" encoding="UTF-8"?>
<configuration version="1.0">
	<step number="1" value="One" />
	<step number="2" value="Two" />
	<step number="3" value="Three" />
</configuration>

The example above is a simple XML file which could be used for holding configuration information or workflow data. JAXB can be used to read this file into Plain Old Java Objects (POJO), but it does require a small amount of work up front creating the POJOs. There are automated ways to create POJOs from XML schema files, but in this article I am going to discuss manual creation.

From the example, you can quickly see there are two POJOs needed for this XML file. The first POJO would be for the Configuration element and the second for the Step element. Essentially, each element in the XML document is represented by a POJO. The example below shows the POJO for the configuration element.

import java.util.List;

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

@XmlRootElement(name="configuration")
public class Configuration {
	
	private String version;
	private List<Step> steps;
	
	@XmlAttribute(name="version")
	public String getVersion() {
		return version;
	}
	
	public void setVersion(String version) {
		this.version = version;
	}
	
	@XmlElement(name="step")
	public List<Step> getSteps() {
		return steps;
	}
	
	public void setSteps(List<Step> steps) {
		this.steps = steps;
	}
}

First, you must define the class which will represent the element. Next, each sub element or attribute should be added as a field. If elements are contained in multiple you define them as a list. Once your fields are created, you then create getters and setters for each field. Finally, you annotate the getters with the appropriate JAXB annotation. The annotations are the key pieces of the POJO.

On the class declaration, the @XmlRootElement annotation is used. The name parameter allows you to define the element name corresponding to your XML. This indicates the POJO shown will represent the configuration element. Attributes of an element are annotated using @XmlAttribute. Again, the name parameter is used to define the value of the attribute corresponding to the XML. Sub elements are annotated with @XmlElement and the same name parameter. For sub elements, additional POJOs are required. I previously mentioned this XML example would require two POJOs.

After creating POJOs, unmarshalling the XML into Java objects is pretty straight forward.

JAXBContext context = JAXBContext.newInstance(Configuration.class);
Unmarshaller m = context.createUnmarshaller();
Configuration c = (Configuration) m.unmarshal(new FileInputStream(new File("configuration.xml")));

From the code snippet above, you can see you first create the JAXBContext object and tell JAXB what the root POJO is expected to be. In our case it is the Configuration object. You then create an Unmarshaller from the previously created JAXBContext. Finally, using the unmarshaller, you unmarshall an InputStream casting the result to the expected object.

Marshalling POJOs to an XML file is just as easy. You once again create a JAXBContext and from that context you create a Marshaller. Then using the marshaller, you marshal the object to an OutputStream. In the example below, the object was marshalled to a FileOutputStream.

JAXBContext context = JAXBContext.newInstance(Configuration.class);
Marshaller mout = context.createMarshaller();
mout.marshal(configuration, new FileOutputStream(outputFile));

This article covered the basic example of creating annotated POJOs, reading XML into Java POJOs, and also writing a POJO to file. There are other uses of JAXB. One for example, is the validation of the XML content. You can also create POJOs automatically from XML specification documents. I will explore each of these topics in future articles.

 

 

 

Leave a Reply

Your email address will not be published.