JAXB Marshaller Example: Converting POJO to XML

The JAXB Marshaller interface is responsible for governing the process of serializing Java content trees i.e. Java objects to XML data. This marshalling from POJO to XML can be done to a variety of output targets.

1. Maven

Start with adding the latest ‘jakarta‘ dependencies for adding the JAXB support (Java 11 onwards).

<dependencies>
  <dependency>
    <groupId>jakarta.xml.bind</groupId>
    <artifactId>jakarta.xml.bind-api</artifactId>
    <version>4.0.0</version>
  </dependency>
</dependencies>

<dependencies>
  <dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
    <version>4.0.3</version>
    <scope>runtime</scope>
  </dependency>
</dependencies>

2. How to Marshal Java Object to XML

2.1. Creating Marshaller

Generally, to create a marshaller we can get the Marshaller instance from the JAXBContext. In the following example, we are creating a marshaller instance for the Employee class. It can be used to convert an instance of the Employee class into XML string.

JAXBContext jaxbContext 	= JAXBContext.newInstance( Employee.class );
Marshaller jaxbMarshaller 	= jaxbContext.createMarshaller();

Employee employeeObj = new Employee(1, "Lokesh", "Gupta", new Department(101, "IT"));

//Overloaded methods to marshal to different outputs
jaxbMarshaller.marshal(employee, System.out);
jaxbMarshaller.marshal(employee, new File("output.xml"));
jaxbMarshaller.marshal(employee, new StringWriter()); 

2.2. Marshal POJO to File

The following code marshals the Employee object and writes the XML into employee.xml file.

OutputStream os = new FileOutputStream( "employee.xml" );
jaxbMarshaller.marshal( employeeObj, os );

2.3. Marshal POJO to SAX ContentHandler

Assume MyContentHandler is instance of org.xml.sax.ContentHandler. The content handler can be used to customize the XML output during the marshalling process.

jaxbMarshaller.marshal( employeeObj, new MyContentHandler() );

2.4. Marshal POJO to DOM Document

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.newDocument();

jaxbMarshaller.marshal( employeeObj, doc );

2.5. Printing XML to Console

We can write the XML to the console, directly. It is useful for debugging purposes.

m.marshal( employeeObj, new PrintWriter( System.out ) );

3. JAXB Marshaller Properties

We can further customize the behavior of marshaller by setting the properties. These properties enable or disable the default behavior.

jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
//or
jaxbMarshaller.setProperty("jakarta.formatted.output", Boolean.TRUE);

All JAXB Providers are required to support the following set of properties. Some providers may support additional properties.

  • jakarta.encoding – The output encoding to use when marshalling the XML data. The Marshaller will use “UTF-8” by default if this property is not specified.
  • jakarta.formatted.output – Value can be true or false. Whether or not the Marshaller will format the resulting XML data with line breaks and indentation. Default value is false.
  • jakarta.schemaLocation – It allows the client application to specify an xsi:schemaLocation attribute in the generated XML data.
  • jakarta.noNamespaceSchemaLocation – It allows the client application to specify an xsi:noNamespaceSchemaLocation attribute in the generated XML data.
  • jakarta.fragment – It determines whether or not document-level events will be generated by the Marshaller. Value can be true or false.

4. Marshaller Callback Methods

We can customize the marshalling operation inside JAXB annotated class e.g. Employee.java. We need to define two methods that will listen before and after the marshaller process in that class. In these methods, we can perform actions such as setting extra fields or modifying the value of existing fields.

In the following example, we are defining the methods beforeMarshal() and afterMarshal() that will be invoked by JAXB marshaller before and after the marshalling is done.

import java.io.Serializable;
import jakarta.xml.bind.Marshaller;
import jakarta.xml.bind.annotation.XmlAccessType;
import jakarta.xml.bind.annotation.XmlAccessorType;
import jakarta.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "employee")
@XmlAccessorType(XmlAccessType.PROPERTY)
public class Employee implements Serializable {

	private static final long serialVersionUID = 1L;

	private Integer id;
	private String firstName;
	private String lastName;
	private Department department;

	public Employee() {
		super();
	}

	//Setters and Getters

	@Override
	public String toString() {
		return "Employee [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", department="
				+ department + "]";
	}

	// Invoked by Marshaller after it has created an instance of this object.
	boolean beforeMarshal(Marshaller marshaller) {
		System.out.println("Before Marshaller Callback");
		return true;
	}

	// Invoked by Marshaller after it has marshalled all properties of this object.
	void afterMarshal(Marshaller marshaller) {
		System.out.println("After Marshaller Callback");
	}
}

5. JAXB Marshalling Example

The following is an example of marshalling an Employee instance to XML String and printing to the console.

import java.io.StringWriter;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import com.howtodoinjava.demo.model.Department;
import com.howtodoinjava.demo.model.Employee;

public class JaxbExample
{
	public static void main(String[] args)
	{
		Employee employee = new Employee(1, "Lokesh", "Gupta", new Department(101, "IT"));

		jaxbObjectToXML(employee);
	}

	private static void jaxbObjectToXML(Employee employee)
	{
	    try {
	        JAXBContext jaxbContext = JAXBContext.newInstance(Employee.class);
	        Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

	        jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); // To format XML

	        //Print XML String to Console
	        jaxbMarshaller.marshal(employee, System.out);

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

Program Output.

Before Marshaller Callback
After Marshaller Callback
 
<?xml version="1.0" encoding="UTF-8"?>
<employee>
   <department>
      <id>101</id>
      <name>IT</name>
   </department>
   <firstName>Lokesh</firstName>
   <id>1</id>
   <lastName>Gupta</lastName>
</employee>

Drop me your questions in the comments section.

Happy Learning !!

Source Code on Github

Comments

Subscribe
Notify of
guest
4 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.

Our Blogs

REST API Tutorial

Dark Mode

Dark Mode