Spring OXM: Marshaller and Unmarshaller Example with Castor
March 05, 2023
On this page, we will learn marshaller and unmarshaller example with Castor in spring OXM.
1. Castor is an open source XML binding framework. It allows to convert XML to/from Java object. We configure
CastorMarshaller
as bean in JavaConfig.
2. If we are using any mapping XML file, we can refer it by using
setMappingLocation
method of CastorMarshaller
.
3. Castor provides
castor.properties
file to override its configurations such as pretty printing of XML.
4. Marshaller: We convert Java object into XML.
Unmarshaller: We convert XML into Java object.
Technologies Used
Find the technologies being used in our example.1. Java
2. Eclipse
3. Gradle
4. Spring-Oxm:4.1.5.RELEASE
Project Structure in Eclipse
Find our demo project structure in Eclipse.
Gradle File
Find the Gradle file to resolve JAR dependencies.build.gradle
apply plugin: 'java' apply plugin: 'eclipse' archivesBaseName = 'concretepage' version = '1' repositories { mavenCentral() } dependencies { compile 'org.springframework.boot:spring-boot-starter:1.2.2.RELEASE' compile 'org.springframework:spring-oxm:4.1.5.RELEASE' compile 'org.codehaus.castor:castor-xml:1.3.3' }
Spring Annotation Configuration for CastorMarshaller
In configuration file, we need to create bean for CastorMarshaller. CastorMarshaller.setMappingLocation() is used to refer xml mapping file. Using CastorMarshaller we create the instance for Marshaller and Unmarshaller.AppConfig.java
package com.concretepage; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.oxm.castor.CastorMarshaller; @Configuration public class AppConfig { @Bean public Converter getHandler(){ Converter handler= new Converter(); handler.setMarshaller(getCastorMarshaller()); handler.setUnmarshaller(getCastorMarshaller()); return handler; } @Bean public CastorMarshaller getCastorMarshaller() { CastorMarshaller castorMarshaller = new CastorMarshaller(); Resource resource = new ClassPathResource("mapping.xml"); castorMarshaller.setMappingLocation(resource); return castorMarshaller; } }
Create Marshaller and Unmarshaller Class
In this class, we create methods for marshaling and unmarshaling. Spring provides two interfaces.org.springframework.oxm.Marshaller org.springframework.oxm.Unmarshaller
Unmarshaller interface defines the object XML mapping unmarshaller.
While writing to XML to file, we use
StreamResult
class.
While converting XML to Java object, we use
StreamSource
class.
Converter.java
package com.concretepage; 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 Converter { private Marshaller marshaller; private Unmarshaller unmarshaller; public void setMarshaller(Marshaller marshaller) { this.marshaller = marshaller; } public void setUnmarshaller(Unmarshaller unmarshaller) { this.unmarshaller = unmarshaller; } //Converts Object to XML file public void doMarshaling(String fileName, Object graph) throws IOException { FileOutputStream fos = null; try { fos = new FileOutputStream(fileName); marshaller.marshal(graph, new StreamResult(fos)); } finally { fos.close(); } } //Converts XML to Java Object public Object doUnMarshaling(String fileName) throws IOException { FileInputStream fis = null; try { fis = new FileInputStream(fileName); return unmarshaller.unmarshal(new StreamSource(fis)); } finally { fis.close(); } } }
Create Setter/Getter Class for XML Mapping
We need to create a setter/getter class which will be used to map object to XML and XML to Object mapping.Country.java
package com.concretepage.bean; public class Country { private Integer id; private String countryName; private String pmName; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getCountryName() { return countryName; } public void setCountryName(String countryName) { this.countryName = countryName; } public String getPmName() { return pmName; } public void setPmName(String pmName) { this.pmName = pmName; } }
XML Pretty Printing
We can perform pretty printing while marshaling. If we need proper indentation of XML tags, we have to overridecastor.properties
file.
The castor.properties
file should be kept in classpath. To achieve pretty printing, configure org.exolab.castor.indent
as true.
castor.properties
org.exolab.castor.indent = true
Map Object and XML
To get the control of creating XML and its node nomenclature and mapping java file properties to a XML attribute or element, we have to create a mapping file which will be configured withCastorMarshaller
in configuration file.
mapping.xml
<?xml version="1.0"?> <!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN" "http://castor.org/mapping.dtd"> <mapping> <description> Spring OXM and Castor </description> <class name="com.concretepage.bean.Country"> <map-to xml="country-info" /> <field name="id" type="int"> <bind-xml name="id" node="attribute"/> </field> <field name="countryName" type="string"> <bind-xml name="country-name" node="element"/> </field> <field name="pmName" type="string"> <bind-xml name="pm-name" node="element"/> </field> </class> </mapping>
Run Application
Finally we will test our application. We will create an object ofCountry
class and call marshaling method. This will generate an XML file as country.xml
. Now we will call method for unmarshaling in which we pass our XML file that will be converted into Java object.
RunApplication.java
package com.concretepage; import java.io.IOException; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.concretepage.bean.Country; public class RunApplication { public static void main(String[] args) throws IOException { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(AppConfig.class); ctx.refresh(); Converter converter = ctx.getBean(Converter.class); //Perform Marshaling Country country = new Country(); country.setId(100); country.setCountryName("India"); country.setPmName("ABC"); converter.doMarshaling("country.xml", country); System.out.println("Marshaling performed"); //Perform UnMarshaling country = (Country)converter.doUnMarshaling("country.xml"); System.out.println("After UnMarshaling Data is: id:"+ country.getId()+", CountryName:"+country.getCountryName()); } }
country.xml
<?xml version="1.0" encoding="UTF-8"?> <country-info id="100"> <country-name>India</country-name> <pm-name>ABC</pm-name> </country-info>
Marshaling performed 11:05:03.124 [main] DEBUG org.exolab.castor.xml.XMLContext - Creating new Unmarshaller instance. After UnMarshaling Data is: id:100, CountryName:India