Thursday, 17 January 2019

XML Marshalling and UnMarshalling using Spring and Castor XML binding framework - XML Config

🚀 Master Spring OXM & Enterprise Java!

Subscribe to Ram N Java for clean code walkthroughs, Spring framework tutorials, and XML binding architecture guides!

🔔 Subscribe to Ram N Java

What Is Spring OXM with XML Configuration?

In enterprise Java applications, exchanging data between systems often relies on converting Java objects to XML and vice versa. Spring OXM (Object/XML Mapping) provides a unified abstraction layer over multiple XML binding toolkits, such as the Castor XML Binding Framework. By leveraging classic Spring XML configuration (applicationContext.xml), developers can decouple binding definitions from Java business code cleanly.

Marshalling vs Unmarshalling

  • Marshalling (Serialization): The process of serializing an in-memory Java object graph into structured XML data (file, output stream, or payload).
  • Unmarshalling (Deserialization): The process of reading an incoming XML document and deserializing it back into Java object instances.
  • CastorMarshaller: The core Spring bean implementing both org.springframework.oxm.Marshaller and org.springframework.oxm.Unmarshaller to drive the Castor transformation engine.

Key Steps for XML-Based Configuration

  1. Configure the CastorMarshaller Bean: Define the castorMarshaller bean in applicationContext.xml and provide the path to your Castor mapping file (e.g., mapping.xml) using the mappingLocation property.
  2. Wire Converter Beans: Inject the castorMarshaller reference into your custom XML conversion service beans for both the marshaller and unmarshaller properties.
  3. Define the Mapping File: Specify explicit mappings in mapping.xml to link XML elements/attributes to target Java fields and classes.
  4. Bootstrap ApplicationContext: Load your Spring container via ClassPathXmlApplicationContext and trigger conversion routines across file streams or strings.

Why Use XML-Based Config for Castor?

  • Centralized Mapping: Externalizing configuration into XML separates data mapping definitions completely from compiled Java classes.
  • Consistent Exception Hierarchy: Spring translates vendor-specific Castor exceptions into unchecked Spring OXM exceptions.
  • Legacy & Enterprise Compatibility: Perfect for maintaining enterprise Spring applications where XML configuration remains standard practice.

Recommended Next Videos

Continue mastering Spring Object/XML Mapping with these related tutorials from our channel:


Click here to watch on Youtube:
https://www.youtube.com/watch?v=vd2kaJzxIQs&list=UUhwKlOVR041tngjerWxVccw

Click the below Image to Enlarge:
XML Marshalling and UnMarshalling using Spring and Castor XML binding framework - XML Config

XML Marshalling and UnMarshalling using Spring and Castor XML binding framework - XML Config

XML Marshalling and UnMarshalling using Spring and Castor XML binding framework - XML Config

XML Marshalling and UnMarshalling using Spring and Castor XML binding framework - XML Config

XML Marshalling and UnMarshalling using Spring and Castor XML binding framework - XML Config

XML Marshalling and UnMarshalling using Spring and Castor XML binding framework - XML Config

XML Marshalling and UnMarshalling using Spring and Castor XML binding framework - XML Config

XML Marshalling and UnMarshalling using Spring and Castor XML binding framework - XML Config

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 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.ram.core</groupId>
    <artifactId>SpringDemo</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>SpringDemo</name>
    <url>http://maven.apache.org</url>

    <properties>
        <spring.version>5.1.1.RELEASE</spring.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.8.2</version>
            <scope>test</scope>
        </dependency>

        <!-- Spring 3 dependencies -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>


        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-oxm</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- Uses Castor for XML -->
        <dependency>
            <groupId>org.codehaus.castor</groupId>
            <artifactId>castor</artifactId>
            <version>1.2</version>
        </dependency>

        <!-- Castor need this -->
        <dependency>
            <groupId>xerces</groupId>
            <artifactId>xercesImpl</artifactId>
            <version>2.8.1</version>
        </dependency>

    </dependencies>
</project>

Customer.java

package com.ram.core.model;

public class Customer
{
    private String name;
    private int age;
    private String address;

    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 String getAddress()
    {
        return address;
    }

    public void setAddress(String address)
    {
        this.address = address;
    }

    @Override
    public String toString()
    {
        return "Customer [name=" + name + ", age=" + age
                + ", address=" + address + "]";
    }

}

customer_mapping.xml

<mapping>
    <class name="com.ram.core.model.Customer">

        <map-to xml="customer" />

        <field name="name" type="string">
            <bind-xml name="name" node="element" />
        </field>

        <field name="age" type="integer">
            <bind-xml name="age" node="attribute" />
        </field>

        <field name="address" type="string">
            <bind-xml name="address" node="element" />
        </field>
    </class>
</mapping>

XMLConverter.java

package com.ram.core;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.springframework.oxm.Marshaller;
import org.springframework.oxm.Unmarshaller;

public class XMLConverter
{

    private Marshaller marshaller;
    private Unmarshaller unmarshaller;

    public Marshaller getMarshaller()
    {
        return marshaller;
    }

    public void setMarshaller(Marshaller marshaller)
    {
        this.marshaller = marshaller;
    }

    public Unmarshaller getUnmarshaller()
    {
        return unmarshaller;
    }

    public void setUnmarshaller(Unmarshaller unmarshaller)
    {
        this.unmarshaller = unmarshaller;
    }

    public void convertFromObjectToXML(Object object, String filepath)
            throws IOException
    {

        FileOutputStream os = null;
        try
        {
            os = new FileOutputStream(filepath);
            getMarshaller().marshal(object, new StreamResult(os));
        }
        finally
        {
            if (os != null)
            {
                os.close();
            }
        }
    }

    public Object convertFromXMLToObject(String xmlfile)
            throws IOException
    {
        FileInputStream is = null;
        try
        {
            is = new FileInputStream(xmlfile);
            return getUnmarshaller().unmarshal(new StreamSource(is));
        }
        finally
        {
            if (is != null)
            {
                is.close();
            }
        }
    }

}

applicationContext.xml

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.3.xsd">


    <bean id="XMLConverter" class="com.ram.core.XMLConverter">
        <property name="marshaller" ref="castorMarshaller" />
        <property name="unmarshaller" ref="castorMarshaller" />
    </bean>
    <bean id="castorMarshaller" class="org.springframework.oxm.castor.CastorMarshaller" >
        <property name="mappingLocation" value="classpath:customer_mapping.xml" />
    </bean>

</beans>

castor.properties

org.exolab.castor.indent = true


App.java

package com.ram.core;

import java.io.IOException;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.ram.core.model.Customer;

public class App
{
    private static final String XML_FILE_NAME = "customer.xml";

    public static void main(String[] args) throws IOException  
    {
        ApplicationContext appContext = new ClassPathXmlApplicationContext(
                "applicationContext.xml");
        XMLConverter converter = (XMLConverter) appContext
                .getBean("XMLConverter");

        Customer customer = new Customer();
        customer.setName("Peter");
        customer.setAge(52);
        customer.setAddress("A505,North Street,Bangalore");

        // from object to XML file
        converter.convertFromObjectToXML(customer, XML_FILE_NAME);
        System.out.println("Converted Object to XML!");

        // from XML to object
        Customer customer2 = (Customer) converter
                .convertFromXMLToObject(XML_FILE_NAME);
        System.out.println(customer2);
        System.out.println("Converted XML to Object!");

    }
}

Output:

Converted Object to XML!
Customer [name=Peter, age=52, address=A505,North Street,Bangalore]
Converted XML to Object!

customer.xml

<?xml version="1.0" encoding="UTF-8"?>
<customer age="52">
    <name>Peter</name>
    <address>A505,North Street,Bangalore</address>
</customer>

Click the below link to download the code:
https://sites.google.com/site/javaspringram2019/java_spring_2019/SpringDemo_Object_XML_mapping_castor_XML_config.zip?attredirects=0&d=1

Github Link:
https://github.com/ramram43210/Java_Spring_2019/tree/master/Spring_2019/SpringDemo_Object_XML_mapping_castor_XML_config

Bitbucket Link:
https://bitbucket.org/ramram43210/java_spring_2019/src/c28445a6034f76c255a473b056641d2ecd4e2cae/Spring_2019/SpringDemo_Object_XML_mapping_castor_XML_config/?at=master

See also:

  • All JavaEE Videos Playlist
  • All JavaEE Videos
  • All JAVA EE Links
  • Spring Tutorial
  • Servlets Tutorial
  • All Design Patterns Links
  • JDBC Tutorial
  • Java Collection Framework Tutorial
  • JAVA Tutorial
  • Kids Tutorial
  • Cooking Tutorial
  • No comments:

    Post a Comment

    Tutorials