The JAXB Marshaller
interface is responsible for governing the process of serializing Java content trees i.e. Java objects to XML data. This marshalling to XML can be done to a variety of output targets.
1. How to Marshal Java Object to XML
1.1. Creating Marshaller
Generally, to create a marshaller we can get the Marshaller instance from the JAXBContext. In following example, we are creating a marshaller instance for the Employee class. It can be used to convert an instance of 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(employeeObj);
1.2. Marshal 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 );
1.3. Marshal 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() );
1.4. Marshal to DOM Document
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.newDocument();
jaxbMarshaller.marshal( employeeObj, doc );
1.5. Printing to Console
We can write the XML to the console, directly. It is useful for debugging purposes.
m.marshal( employeeObj, new PrintWriter( System.out ) );
2. 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("jaxb.formatted.output", Boolean.TRUE);
All JAXB Providers are required to support the following set of properties. Some providers may support additional properties.
- jaxb.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. - jaxb.formatted.output – Value can be
true
orfalse
. Whether or not theMarshaller
will format the resulting XML data with line breaks and indentation. Default value isfalse
. - jaxb.schemaLocation – It allows the client application to specify an
xsi:schemaLocation
attribute in the generated XML data. - jaxb.noNamespaceSchemaLocation – It allows the client application to specify an
xsi:noNamespaceSchemaLocation
attribute in the generated XML data. - jaxb.fragment – It determines whether or not document level events will be generated by the Marshaller. Value can be
true
orfalse
.
3. 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 javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.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");
}
}
4. 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 !!
Comments