Saturday, December 25, 2021

Spring Object XML Mapping (OXM) JAXB Example

In this post we’ll see how to serialize an object graph to XML (marshalling) and how to deserialize the XML to an object graph (unmarshalling) using JAXB and Spring OXM module.

Spring Object-XML mapping support

Spring framework provides support for converting an XML document to/from an object using Spring-OXM module.

Spring-OXM provides abstractions to the O/X mapping frameworks through two interfaces - Marshaller and Unmarshaller.

These abstractions allow you to switch O/X mapping frameworks with relative ease, with little or no changes required on the classes that do the marshalling.

The implementation classes provided by Spring-OXM for these interfaces are-

  1. Jaxb2Marshaller- For object-XML mapping using JAXB.
  2. CastorMarshaller- For object-XML mapping using Castor. Refer Spring Object XML Mapping Support - Castor Example to see an example of XML marshalling-unmarshalling in Spring using Castor.
  3. JibxMarshaller- For object-XML mapping using JIBX.

Object to XML mapping using JAXB – Spring Example

In this example we’ll see how to do XML marshalling and unmarshalling using JAXB and Spring-OXM.

Maven dependencies

Along with Spring core dependencies you’ll need following dependencies for JAXB and Spring-OXM.

<properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <java.version>10</java.version>
  <spring.version>5.0.8.RELEASE</spring.version>
</properties>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-oxm</artifactId>
  <version>${spring.version}</version>
</dependency>
<dependency>
  <groupId>javax.xml.bind</groupId>
  <artifactId>jaxb-api</artifactId>
  <version>2.3.0</version>
</dependency>
<dependency>
  <groupId>com.sun.xml.bind</groupId>
  <artifactId>jaxb-impl</artifactId>
  <version>2.3.0</version>
</dependency>
<dependency>
  <groupId>com.sun.xml.bind</groupId>
  <artifactId>jaxb-core</artifactId>
  <version>2.3.0</version>
</dependency>

Bean classes

Two classes are used in this XML marshalling and unmarshalling example, User class whose objects are returned in the XML form and UserListContainer class which contains the List of objects of type User.

User.java

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

@XmlRootElement
@XmlType(propOrder = {"firstName", "lastName", "email"})
public class User {
  private int id;
  private String firstName;
  private String lastName;
  private String email;
  public User() {
    
  }
  public User(int id, String firstName, String lastName, String email) {
    this.id = id;
    this.firstName = firstName;
    this.lastName = lastName;
    this.email = email;
  }
  @XmlAttribute(name="id")
  public int getId() {
    return id;
  }
  public void setId(int id) {
    this.id = id;
  }

  public String getFirstName() {
    return firstName;
  }
  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }
  public String getLastName() {
    return lastName;
  }
  public void setLastName(String lastName) {
    this.lastName = lastName;
  }
  public String getEmail() {
    return email;
  }
  public void setEmail(String email) {
    this.email = email;
  }
  @Override
  public String toString() {
    return "id- " + getId() + " First Name- " + getFirstName() + 
      " Last Name- " + getLastName() + " Email- " + getEmail();
  }
}

UserListContainer.java

@XmlRootElement(name="users")
public class UserListContainer {
  private List<User> userList;

  @XmlElement(name = "user")
  public List<User> getUserList() {
    return userList;
  }

  public void setUserList(List<User> userList) {
    this.userList = userList;
  }
}

As you can see in these classes JAXB annotations are used-

@XmlRootElement- To specify the root element for the XML.
@XmlElement- To specify the elements in XML.
@XmlAttribute- To specify the element attribute.
@XmlType(propOrder = ..)- Specifies the order for XML Schema elements.

Spring XML Configuration for JAXB2Marshaller

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/task
    http://www.springframework.org/task/spring-task.xsd">


  <bean id="jaxb2Marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
    <property name="classesToBeBound">
      <list>
        <value>org.netjs.model.User</value>
        <value>org.netjs.model.UserListContainer</value>
      </list>
    </property>
  </bean>  
  <bean id="objXmlmapper" class="org.netjs.service.ObjXMLMapper">
    <property name="marshaller" ref="jaxb2Marshaller" />
    <property name="unmarshaller" ref="jaxb2Marshaller" />
  </bean>
</beans>

With JAXB2Marshaller bean you can define the classes which are used in Marshalling. Since JAXB2Marshaller class implements both the Marshaller and Unmarshaller interfaces so the same bean is provided as reference for both marshaller and unmarshaller properties in ObjXMLMapper bean.

ObjXMLMapper.java

This is the class where marshalling and unmarshalling is done using the JAXB2Marshaller class in Spring-OXM. In the class Marshaller and Unmarshaller interfaces are used which are set to JAXB2Marshaller instance using the Spring configuration.
public class ObjXMLMapper {
  private static final String FILE_NAME = "users.xml";
  private Marshaller marshaller;
  private Unmarshaller unmarshaller;
  public void setMarshaller(Marshaller marshaller) {
    this.marshaller = marshaller;
  }
  public void setUnmarshaller(Unmarshaller unmarshaller) {
    this.unmarshaller = unmarshaller;
  }
  // Converting object graph to XML (marshalling)
  public void objToXML() throws IOException {
    // call to get object graph
    UserListContainer userList = getUsers();
    try (FileOutputStream os = new FileOutputStream(FILE_NAME)) {            
      this.marshaller.marshal(userList, new StreamResult(os));        
    } 
  }
  // Converting XML to an object graph (unmarshalling) 
  public void XMLToObj() throws IOException {
    UserListContainer userList = new UserListContainer();
    try (FileInputStream is = new FileInputStream(FILE_NAME)) {            
      userList = (UserListContainer)this.unmarshaller.unmarshal(new StreamSource(is));        
    } 
    userList.getUserList().forEach(System.out::println);
  }
    
  public UserListContainer getUsers(){
    List<User> users = getListOfUsers();
    UserListContainer userList = new UserListContainer();
    userList.setUserList(users);
    return userList;
  }
  // Dummy method for adding List of Users
  private List<User> getListOfUsers() {
    List<User> users = new ArrayList<User>();
    users.add(new User(1, "Jack", "Reacher", "abc@xyz.com"));
    users.add(new User(2, "Remington", "Steele", "rs@cbd.com"));
    users.add(new User(3, "Jonathan", "Raven", "jr@sn.com"));
    return users;
  }
}
Class used to run the applications.
public class App {
  public static void main( String[] args ){  
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext
                                               ("appcontext.xml");
    ObjXMLMapper objXMLMapper = context.getBean("objXmlmapper", ObjXMLMapper.class);

    try {
      objXMLMapper.objToXML();
      objXMLMapper.XMLToObj();
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    context.close();
  }
}

On running you get the XML as follows after the object graph is serialized to XML-

<?xml version="1.0" encoding="UTF-8" standalone="true"?>
<users>
  <user id="1">
    <firstName>Jack</firstName>
    <lastName>Reacher</lastName>
    <email>abc@xyz.com</email>
  </user>
  <user id="2">
    <firstName>Remington</firstName>
    <lastName>Steele</lastName>
    <email>rs@cbd.com</email>
  </user>
  <user id="3">
    <firstName>Jonathan</firstName>
    <lastName>Raven</lastName>
    <email>jr@sn.com</email>
  </user>
</users>
Deserializing the XML to object graph displays the object fields on the console-
id- 1 First Name- Jack Last Name- Reacher Email- abc@xyz.com
id- 2 First Name- Remington Last Name- Steele Email- rs@cbd.com
id- 3 First Name- Jonathan Last Name- Raven Email- jr@sn.com

That's all for this topic Spring Object XML Mapping (OXM) JAXB Example. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Spring Tutorial Page


Related Topics

  1. Spring MVC Pagination Example Using PagedListHolder
  2. Spring MVC Generate Response as XML Example
  3. Connection Pooling Using C3P0 Spring Example
  4. Spring Integration With Quartz Scheduler
  5. Spring Web Reactive - Spring WebFlux Example Using Annotation-Based Programming

You may also like-

  1. Spring Asynchronous Method Execution Support Using @Async Annotation
  2. Sending Email Using Spring Framework Example
  3. Circular Dependency in Spring Framework
  4. Autowiring Using Annotations in Spring
  5. ThreadPoolExecutor - Java Thread Pooling With ExecutorService
  6. TypeWrapper Classes in Java
  7. How to Format Date in Java Using SimpleDateFormat
  8. Installing Ubuntu Along With Windows

No comments:

Post a Comment