JAXB marshalling: from Java object to XML

In this post we see an example of XML serialization, called in this context marshalling, of a Java object through JAXB , the Java Architecture for XML Binding, that is, the APIs provided by the Java platform, both Standard and Enterprise, to map an XML schema into a Java object and vice versa.

For our purposes, I used a simple Spring Boot project created with its IDE Spring Tool Suite, but it is actually a normal Java project with no special requirements.

After creating the project, we create a package named “model” where we create the class that represents our entity of which we are going to convert to XML the instances.
Let’s create for example the “User” class, with the following properties:

  • id
  • firstName
  • lastName
  • website
  • email

The User class code will be:

public class User {

	private long id;
	private String firstName;
	private String lastName;
	private String website;
	private String email;

	// GETTERS and SETTERS omitted for simplicity
}

JAXB class model User

At this point we must indicate what will be the structure of our resulting XML and what properties of our class we want to insert on it.
To do this we need to define:

  • The root of our XML document
  • Elements to be inserted into the XML
  • Attributes to be inserted into XML elements

To satisfy these requests JAXB provides us three annotations, which are respectively:

  • @XmlRootElement
  • @XmlElement
  • @XmlAttribute

The first one must be applied at the class level

@XmlRootElement
public class User {

}

while the other two must be applied at class property level, specifying that we want access them to create the bindings using the notation @XmlAccessorType(XmlAccessType.FIELD), otherwise JAXB uses as default XmlAccessType.PUBLIC_MEMBER that generates bindings for both annotated properties and for those who have a public getter.

@XmlRootElement()
@XmlAccessorType(XmlAccessType.FIELD)
public class User {

	@XmlElement
	private long id;
	@XmlElement
	private String firstName;
	@XmlElement
	private String lastName;
	@XmlElement
	private String website;
	@XmlElement
	private String email;

	// GETTERS and SETTERS omitted for simplicity
}

Esempio classe Java annotata con JAXB
At this point we have to create a simple test application to verify that the XML serialization of an instance of our class works properly. Since we started from a SpringBoot application, we go in the main class of our application, in this case “JaxbExample2Application.java”, and comment the first line that is, the one where the application is started. This is because in reality we do not need to start all the entire SpringBoot stack, but just to use the main to instantiate an object and print in output its XML serialization.

The steps to be performed to achieve what we just said are:

  • Instantiate an object of the User class
  • Create a JAXB context (JAXBContext)
  • Create a Marshaller
  • Invoke the marshal method of the Marshaller, passing it the User object and the output stream as parameters

To meet the first point, we create for simplicity the full-args constructor for the User class.

@XmlRootElement()
@XmlAccessorType(XmlAccessType.FIELD)
public class User {
	
	@XmlElement
	private long id;
	@XmlElement
	private String firstName;
	@XmlElement
	private String lastName;
	@XmlElement
	private String website;
	@XmlElement
	private String email;
	
	public User(long id, String firstName, String lastName, String website, String email) {
		super();
		this.id = id;
		this.firstName = firstName;
		this.lastName = lastName;
		this.website = website;
		this.email = email;
	}
	
	// GETTERS and SETTERS omitted for simplicity
}

and then in the class of our application we use it to create an instance of the class:

User u = new User(0, "Davis", "Molinari", "www.davismol.net", "myemailaddress@gmail.com");

At this point we can create the JAXB context

JAXBContext jc = JAXBContext.newInstance(User.class);

and the Marshaller, even setting the property to format in a legible way the output of XML Serialization

Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

Finally, we can invoke the marshal() method on the Marshaller, passing it the object of the User class and the stream on which we want to write the XML, which in this case will be the console, so System.out

marshaller.marshal(u, System.out);

All this could generate some exception, so the sequence must be enclosed in a try-multicatch block. The complete application code to test the marshalling becomes:

public class JaxbExample2Application {

	public static void main(String[] args) {
		//SpringApplication.run(JaxbExample2Application.class, args);
		User u = new User(0, "Davis", "Molinari", "www.davismol.net", "myemailaddress@gmail.com");
		
		try {
			JAXBContext jc = JAXBContext.newInstance(User.class);

			Marshaller marshaller = jc.createMarshaller();
			marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
			marshaller.marshal(u, System.out);
			
		} catch (PropertyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (JAXBException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

Let’s try to run our application and …

JAXB Java no args constructor missing error
We got an error!

In our class we must also add the zero arguments constructor otherwise, attempting to perform the XML serialization of an instance, we get the following error:

com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
net.davismol.model.User does not have a no-arg default constructor.
	this problem is related to the following location:
		at net.davismol.model.User

So let’s add the no-args constructor

@XmlRootElement()
@XmlAccessorType(XmlAccessType.FIELD)
public class User {
	
	@XmlElement
	private long id;
	@XmlElement
	private String firstName;
	@XmlElement
	private String lastName;
	@XmlElement
	private String website;
	@XmlElement
	private String email;
	
	public User() {
	    super();
	}
	
	// GETTERS and SETTERS omitted for simplicity
}

and try to run the application again. This time the execution is successful and the result shown as output is the following:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<user>
    <id>0</id>
    <firstName>Davis</firstName>
    <lastName>Molinari</lastName>
    <website>www.davismol.net</website>
    <email>myemailaddress@gmail.com</email>
</user>

JAXB XML marshalling of a Java object
So far we have only seen the use the @XmlElement annotation and we have not considered @XmlAttribute. Let us now instead to use it, in order to define that a particular property must not be generated in the XML as an element but rather as an attribute of the root node, “user” in this case.
Let’s take for example the “email” property of the User class and to annotate it with @XmlAttribute instead of @XmlElement

@XmlRootElement()
@XmlAccessorType(XmlAccessType.FIELD)
public class User {
	
	@XmlElement
	private long id;
	@XmlElement
	private String firstName;
	@XmlElement
	private String lastName;
	@XmlElement
	private String website;
	@XmlAttribute
	private String email;

	public User() {
		super();
	}

	// GETTERS and SETTERS omitted for simplicity
}

If we try to run the application again we get the following result:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<user email="myemailaddress@gmail.com">
    <id>0</id>
    <firstName>Davis</firstName>
    <lastName>Molinari</lastName>
    <website>www.davismol.net</website>
</user>

where we see that the “email” tag has disappeared from the XML and its value has been instead added as an attribute of the “user” element.

JAXB marshalling Java with XMLAttribute

The entire sample project can be downloaded here:

This entry was posted in $1$s. Bookmark the permalink.

Leave a Reply

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