Spring OXM - Quick Guide



Spring OXM - Overview

The Spring Framework provides Object/XML or O/X mapping using global marshaller/unmarshaller interfaces and allows to switch O/X mapping frameworks easily. This process of converting an object to XML is called XML Marshalling/Serialization and conversion from XML to object is called XML Demarshalling/Deserialization.

Spring framework provides a Marshaller and UnMarshaller interfaces where Marshaller interface is responsible to marshall an object to XML and UnMarshaller interface deserializes the xml to an object.

Benefits of Spring OXM?

Following are the key benefits of using Spring OXM framework.

  • Easy Configuration − Using spring bean context factory, creation of marshaller/unmarshaller is quite easy and is configurable without worrying about O/X libraries structures like JAXB Context, JiBX binding factories etc. A marsaller/unmarshaller can be configured as any other bean.

  • Consistent Interfacing − Marshaller and UnMarshaller are global interfaces. These interfaces provides an abstraction layer over other O/X mapping frameworks and allows to switch between them without changing the code or with little code change.

  • Consistent Exception Handling − All underlying exceptions are mapped to a XmlMappingException as root exception. Thus developers need not to worry about underlying O/X mapping tool own exception hiearchy.

Marshaller

Marshaller is an interface with single method marshal.

public interface Marshaller {
   /**
    * Marshals the object graph with the given root into the provided Result.
   */
   void marshal(Object graph, Result result)
      throws XmlMappingException, IOException;
}

Where graph is any object to be marshalled and result is a tagging interface to represent the XML output. Following are the available types −

  • javax.xml.transform.dom.DOMResult − Represents org.w3c.dom.Node.

  • javax.xml.transform.sax.SAXResult − Represents org.xml.sax.ContentHandler.

  • javax.xml.transform.stream.StreamResult − Represents java.io.File, java.io.OutputStream, or java.io.Writer.

UnMarshaller

UnMarshaller is an interface with single method unmarshal.

public interface UnMarshaller {
   /**
    * Unmarshals the given provided Source into an object graph.
   */
   Object unmarshal(Source source)
      throws XmlMappingException, IOException;
}

Where source is a tagging interface to represent the XML input. Following are the available types −

  • javax.xml.transform.dom.DOMSource − Represents org.w3c.dom.Node.

  • javax.xml.transform.sax.SAXSource − Represents org.xml.sax.InputSource, and org.xml.sax.XMLReader.

  • javax.xml.transform.stream.StreamSource − Represents java.io.File, java.io.InputStream, or java.io.Reader.

Spring OXM - Environment Setup

This chapter will guide you on how to prepare a development environment to start your work with Spring and its OXM Capabilities. It will also teach you how to set up JDK on your machine before you set up spring −

Setup Java Development Kit (JDK)

You can download the latest version of SDK from Oracle's Java site − Java SE Downloads. You will find instructions for installing JDK in downloaded files, follow the given instructions to install and configure the setup. Finally set PATH and JAVA_HOME environment variables to refer to the directory that contains java and javac, typically java_install_dir/bin and java_install_dir respectively.

If you are running Windows and have installed the JDK in C:\jdk-24, you would have to put the following line in your C:\autoexec.bat file.

set PATH=C:\jdk-24;%PATH% 
set JAVA_HOME=C:\jdk-24

Alternatively, on Windows NT/2000/XP, you will have to right-click on My Computer, select Properties → Advanced → Environment Variables. Then, you will have to update the PATH value and click the OK button.

On Unix (Solaris, Linux, etc.), if the SDK is installed in /usr/local/jdk-24 and you use the C shell, you will have to put the following into your .cshrc file.

setenv PATH /usr/local/jdk-24/bin:$PATH 
setenv JAVA_HOME /usr/local/jdk-24

Alternatively, if you use an Integrated Development Environment (IDE) like Borland JBuilder, Eclipse, IntelliJ IDEA, or Sun ONE Studio, you will have to compile and run a simple program to confirm that the IDE knows where you have installed Java. Otherwise, you will have to carry out a proper setup as given in the document of the IDE.

Popular Java Editors

To write your Java programs, you need a text editor. There are many sophisticated IDEs available in the market. But for now, you can consider one of the following −

  • Notepad − On Windows machine, you can use any simple text editor like Notepad (Recommended for this tutorial), TextPad.

  • Netbeans − It is a Java IDE that is open-source and free, which can be downloaded from www.netbeans.org/index.html.

  • Eclipse − It is also a Java IDE developed by the eclipse open-source community and can be downloaded from www.eclipse.org.

Install Eclipse

In this chapter, we will explain how to set Spring environment in Eclipse IDE. Before proceeding with the installation, make sure that you already have Eclipse installed in your system. If not, download and install Eclipse.

For more information on Eclipse, please refer our Eclipse Tutorial

Set Maven

In this tutorial, we are using maven to run and build the spring based examples. Follow the Maven - Environment Setup to install maven.

Spring OXM - Create Project

Using eclipse, select FileNewMaven Project. Tick the Create a simple project (skip archetype selection) and click Next.

Enter the details, as shown below −

  • groupId − com.tutorialspoint

  • artifactId − springoxm

  • version − 0.0.1-SNAPSHOT

  • name − Spring OXM

  • description − Spring OXM Project

Click on Finish button and a new project will be created.

pom.xml

You can check the default content of pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
   
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.tutorialspoint</groupId>
   <artifactId>springoxm</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <name>Spring OXM</name>
   <description>Spring OXM Project</description>
</project>

Now as we've our project ready, let add following dependencies in pom.xml in next chapter.

  • Spring Context

  • Spring OXM

  • JAXB

Spring OXM - Update Project for JAXB

Update the content of pom.xml to have spring core, spring oxm and jaxb dependencies as shown below −

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.tutorialspoint</groupId>
   <artifactId>springoxm</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <name>Spring OXM</name>
   <description>Spring OXM Project</description>
   <properties>
      <java.version>24</java.version>
      <org.springframework.version>7.0.0-M9</org.springframework.version>
      <xml.bind.version>4.0.4</xml.bind.version>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   </properties>
   <build>      
      <plugins>
         <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.7.0</version>
            <configuration>
               <source>${java.version}</source>
               <target>${java.version}</target>
            </configuration>
         </plugin>
      </plugins>
   </build>
   <dependencies>
      <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-context</artifactId>
         <version>${org.springframework.version}</version>
         <scope>compile</scope>
      </dependency>
      <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-oxm</artifactId>
         <version>${org.springframework.version}</version>
      </dependency>
      <dependency>
         <groupId>jakarta.xml.bind</groupId>
         <artifactId>jakarta.xml.bind-api</artifactId>
         <version>${xml.bind.version}</version>
      </dependency>
      <dependency>
         <groupId>org.glassfish.jaxb</groupId>
         <artifactId>jaxb-runtime</artifactId>
         <version>${xml.bind.version}</version>
         <scope>runtime</scope>
      </dependency>
   </dependencies>
</project>

Create a class Student.java with O/X Annotation as shown below.

Student.java

package com.tutorialspoint.oxm.model;

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

@XmlRootElement
public class Student{
   String name;
   int age;
   int id;

   public String getName(){
      return name;
   }
   @XmlElement
   public void setName(String name){
      this.name = name;
   }
   public int getAge(){
      return age;
   }
   @XmlElement
   public void setAge(int age){
      this.age = age;
   }
   public int getId(){
      return id;
   }
   @XmlAttribute
   public void setId(int id){
      this.id = id;
   }
}

Create applicationcontext.xml in src → main → resources with the following content.

applicationcontext.xml

<?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:oxm="http://www.springframework.org/schema/oxm"  
   xsi:schemaLocation="http://www.springframework.org/schema/beans   
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd   
   http://www.springframework.org/schema/oxm  
   http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd">  

   <oxm:jaxb2-marshaller id="jaxbMarshaller">  
      <oxm:class-to-be-bound name="com.tutorialspoint.oxm.model.Student"/>  
   </oxm:jaxb2-marshaller>  
</beans>  

Spring OXM - Test Project for JAXB

Create a main class OxmApplication.java with marshaller and unmarshaller objects. The objective of this class is to marshall a student object to student.xml using marshaller object and then unmarshall the student.xml to student object using unmarshaller object.

OxmApplication.java

package com.tutorialspoint.oxm;

import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.oxm.Marshaller;
import org.springframework.oxm.Unmarshaller;
import org.springframework.oxm.XmlMappingException;
import com.tutorialspoint.oxm.model.Student;

public class OxmApplication {
   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("applicationcontext.xml");  
      Marshaller marshaller = (Marshaller)context.getBean("jaxbMarshaller");
      Unmarshaller unmarshaller = (Unmarshaller)context.getBean("jaxbMarshaller");

      // create student object
      Student student = new Student();
      student.setAge(14);
      student.setName("Soniya");

      try {
         marshaller.marshal(student, new StreamResult(new FileWriter("student.xml")));  
         System.out.println("Student marshalled successfully.");  
         FileInputStream is =  new FileInputStream("student.xml");
         Student student1 = (Student)unmarshaller.unmarshal(new StreamSource(is));
         System.out.println("Age: " + student1.getAge() + ", Name: " + student1.getName());
      } catch(IOException | XmlMappingException ex) {
         ex.printStackTrace();
      }
   }
}

Output

Now in eclipse, right click on the MainApp.java, select Run As context menu, and select Java Application. Check the console logs in the eclipse. You can see the below logs −

Student marshalled successfully.
Age: 14, Name: Soniya

Spring OXM - Update Project for XStream

We can use XStream instead of JAXB library to marshall/unmarshall an XML content.

Update the content of pom.xml to have xstream dependencies as shown below −

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.tutorialspoint</groupId>
   <artifactId>springoxm</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <name>Spring OXM</name>
   <description>Spring OXM Project</description>
   <properties>
      <java.version>24</java.version>
      <org.springframework.version>7.0.0-M9</org.springframework.version>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   </properties>
   <build>      
      <plugins>
         <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.7.0</version>
            <configuration>
               <source>${java.version}</source>
               <target>${java.version}</target>
            </configuration>
         </plugin>
      </plugins>
   </build>
   <dependencies>
      <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-context</artifactId>
         <version>${org.springframework.version}</version>
         <scope>compile</scope>
      </dependency>
      <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-oxm</artifactId>
         <version>${org.springframework.version}</version>
      </dependency>
      <dependency>
         <groupId>com.thoughtworks.xstream</groupId>
         <artifactId>xstream</artifactId>
         <version>1.4.21</version>
         <scope>compile</scope>
      </dependency>     
   </dependencies>
</project>

Update Student.java as shown below.

Student.java

package com.tutorialspoint.oxm.model;

public class Student {
   String name;
   int age;
   int id;

   public String getName(){
      return name;
   }
   public void setName(String name){
      this.name = name;
   }
   public int getAge(){
      return age;
   }
   public void setAge(int age){
      this.age = age;
   }
   public int getId(){
      return id;
   }
   public void setId(int id){
      this.id = id;
   }
}

Update applicationcontext.xml as shown below.

applicationcontext.xml

<?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:oxm="http://www.springframework.org/schema/oxm"  
   xsi:schemaLocation="http://www.springframework.org/schema/beans   
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd   
   http://www.springframework.org/schema/oxm  
   http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd">  

   <bean id="xstreamMarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller">  
      <property name="annotatedClasses" value="com.tutorialspoint.oxm.model.Student">>/property>  
   </bean>   
</beans>  

Spring OXM - Test Project for XStream

Update the OxmApplication.java with marshaller and unmarshaller objects. The objective of this class is to marshall a student object to student.xml using marshaller object and then unmarshall the student.xml to student object using unmarshaller object.

XStream restricts the unmarshelling of object by default. We're giving all permission using following line −

//add permission
unmarshaller.getXStream().addPermission(AnyTypePermission.ANY);

OxmApplication.java

package com.tutorialspoint.oxm;

import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;

import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.oxm.XmlMappingException;
import org.springframework.oxm.xstream.XStreamMarshaller;

import com.thoughtworks.xstream.security.AnyTypePermission;
import com.tutorialspoint.oxm.model.Student;

public class OxmApplication {
   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("applicationcontext.xml");  
      XStreamMarshaller marshaller = (XStreamMarshaller)context.getBean("xstreamMarshaller");
      XStreamMarshaller unmarshaller = (XStreamMarshaller)context.getBean("xstreamMarshaller");

      //add permission
      unmarshaller.getXStream().addPermission(AnyTypePermission.ANY);
      // create student object
      Student student = new Student();
      student.setAge(14);
      student.setName("Soniya");

      try {
         marshaller.marshal(student, new StreamResult(new FileWriter("student.xml")));  
         System.out.println("Student marshalled successfully.");  
         FileInputStream is =  new FileInputStream("student.xml");
         Student student1 = (Student)unmarshaller.unmarshal(new StreamSource(is));
         System.out.println("Age: " + student1.getAge() + ", Name: " + student1.getName());
      } catch(IOException | XmlMappingException ex) {
         ex.printStackTrace();
      }
   }
}

Output

Now in eclipse, right click on the MainApp.java, select Run As context menu, and select Java Application. Check the console logs in the eclipse. You can see the below logs −

Student marshalled successfully.
Age: 14, Name: Soniya

Spring OXM - Update Project for Castor

We can use Castor instead of JAXB library to marshall/unmarshall an XML content. Castor is no more supported by Spring as it is not actively maintained for long time. This tutorial is written using older version of spring.

Update the content of pom.xml to have xstream dependencies as shown below −

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
   
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.tutorialspoint</groupId>
   <artifactId>springoxm</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <name>Spring OXM</name>
   <description>Spring OXM Project</description>
   <properties>
      <org.springframework.version>4.3.7.RELEASE</org.springframework.version>
      <org.hibernate.version>5.2.9.Final</org.hibernate.version>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <java.version>1.8</java.version>    
   </properties> 	
   <dependencies>
      <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-context</artifactId>
         <version>${org.springframework.version}</version>
         <scope>compile</scope>
      </dependency>
      <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-oxm</artifactId>
         <version>${org.springframework.version}</version>
         <scope>compile</scope>
      </dependency>
      <dependency>
         <groupId>org.codehaus.castor</groupId>
         <artifactId>castor-core</artifactId>
         <version>1.4.1</version>
      </dependency>   
      <dependency>
         <groupId>org.codehaus.castor</groupId>
         <artifactId>castor-xml</artifactId>
         <version>1.4.1</version>
      </dependency>
   </dependencies>
   <build>
      <plugins>
         <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <configuration>
               <source>${java.version}</source>
               <target>${java.version}</target>
            </configuration>
         </plugin>
      </plugins>
   </build>
</project>

Add a mapping xml required for castor mapping to map Student class as mappings.xml under src → main → resources folder as shown below.

mappings.xml

<?xml version="1.0"?>  
<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN" "http://castor.org/mapping.dtd">  
<mapping>  
   <class name="com.tutorialspoint.oxm.model.Student" auto-complete="true" >  
      <map-to xml="Student"/>  
      <field name="id" type="integer">  
         <bind-xml name="id" node="attribute"></bind-xml>  
      </field>  
      <field name="name">  
         <bind-xml name="name"></bind-xml>  
      </field>  
      <field name="age">  
         <bind-xml name="age" type="int"></bind-xml>  
      </field>          
   </class>      
</mapping>

Update applicationcontext.xml in src → main → resources with the following content to use CastorMarshaller. CastorMarshaller object can be used for both marshalling and unmarshalling.

applicationcontext.xml

<?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:oxm="http://www.springframework.org/schema/oxm"  
   xsi:schemaLocation="http://www.springframework.org/schema/beans   
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd   
   http://www.springframework.org/schema/oxm  
   http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd">  

   <bean id="castorMarshaller" class="org.springframework.oxm.castor.CastorMarshaller">  
      <property name="targetClass" value="com.tutorialspoint.oxm.model.Student"></property>  
      <property name="mappingLocation" value="mappings.xml"></property>  
   </bean>  
</beans>  

Spring OXM - Test Project for Castor

Update the OxmApplication.java with marshaller and unmarshaller objects. The objective of this class is to marshall a student object to student.xml using marshaller object and then unmarshall the student.xml to student object using unmarshaller object.

OxmApplication.java

package com.tutorialspoint.oxm;

import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.oxm.Marshaller;
import org.springframework.oxm.Unmarshaller;
import org.springframework.oxm.XmlMappingException;
import com.tutorialspoint.oxm.model.Student;

public class OxmApplication {
   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("applicationcontext.xml");  
      Marshaller marshaller = (Marshaller)context.getBean("castorMarshaller");
      Unmarshaller unmarshaller = (Unmarshaller)context.getBean("castorMarshaller");

      // create student object
      Student student = new Student();
      student.setAge(14);
      student.setName("Soniya");

      try {
         marshaller.marshal(student, new StreamResult(new FileWriter("student.xml")));  
         System.out.println("Student marshalled successfully.");  
         FileInputStream is =  new FileInputStream("student.xml");
         Student student1 = (Student)unmarshaller.unmarshal(new StreamSource(is));
         System.out.println("Age: " + student1.getAge() + ", Name: " + student1.getName());
      } catch(IOException | XmlMappingException ex) {
         ex.printStackTrace();
      }
   }
}

Output

Now in eclipse, right click on the MainApp.java, select Run As context menu, and select Java Application. Check the console logs in the eclipse. You can see the below logs −

Student marshalled successfully.
Age: 14, Name: Soniya
Advertisements