Spring Object/XML mapping example

The Spring’s Object/XML Mapping, is converting Object to XML or vice verse. This process is also known as

  1. XML Marshalling – Convert Object to XML.
  2. XML UnMarshalling – Convert XML to Object.

In this tutorial, we show you how to use Spring’s oxm to do the conversion, Object <--- Spring oxm ---> XML.

Note
No nonsense, for why and what benefits of using Spring’s oxm, read this official Spring Object/XML mapping article.

1. Project Dependency

Dependencies in this example.

Note
Spring’s oxm itself doesn’t handle the XML marshalling or UnMarshalling, it depends developer to inject their prefer XML binding framework. In this case, you will use Castor binding framework.

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

	<dependencies>

		<!-- 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>

		<!-- spring oxm -->
		<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>

2. Simple Object

A simple object, later convert it into XML file.


package com.mkyong.core.model;

public class Customer {

	String name;
	int age;
	boolean flag;
	String address;

	//standard getter, setter and toString() methods.
}

3. Marshaller and Unmarshaller

This class will handle the conversion via Spring’s oxm interfaces : Marshaller and Unmarshaller.


package com.mkyong.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();
			}
		}
	}

}

4. Spring Configuration

In Spring’s bean configuration file, inject CastorMarshaller as the XML binding framework.


<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-3.0.xsd">

	<bean id="XMLConverter" class="com.mkyong.core.XMLConverter">
		<property name="marshaller" ref="castorMarshaller" />
		<property name="unmarshaller" ref="castorMarshaller" />
	</bean>
	<bean id="castorMarshaller" class="org.springframework.oxm.castor.CastorMarshaller" />

</beans>

5. Test

Run it.


package com.mkyong.core;

import java.io.IOException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.mkyong.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("App.xml");
		XMLConverter converter = (XMLConverter) appContext.getBean("XMLConverter");
		
		Customer customer = new Customer();
		customer.setName("mkyong");
		customer.setAge(30);
		customer.setFlag(true);
		customer.setAddress("This is address");
		
		System.out.println("Convert Object to XML!");
		//from object to XML file
		converter.convertFromObjectToXML(customer, XML_FILE_NAME);
		System.out.println("Done \n");
		
		System.out.println("Convert XML back to Object!");
		//from XML to object
		Customer customer2 = (Customer)converter.convertFromXMLToObject(XML_FILE_NAME);
		System.out.println(customer2);
		System.out.println("Done");
		
	}
}

Output


Convert Object to XML!
Done 

Convert XML back to Object!
Customer [name=mkyong, age=30, flag=true, address=This is address]
Done

The following XML file “customer.xml” is generated in your project root folder.

File : customer.xml


<?xml version="1.0" encoding="UTF-8"?>
<customer flag="true" age="30">
	<address>This is address</address>
	<name>mkyong</name>
</customer>

Castor XML Mapping

Wait, why flag and age are converted as attribute? Is that a way to control which field should use as attribute or element? Of course, you can use Castor XML mapping to define the relationship between Object and XML.

Create following mapping file, and put it into your project classpath.

File : mapping.xml


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

		<map-to xml="customer" />

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

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

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

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

In Spring bean configuration file, inject above mapping.xml into CastorMarshaller via “mappingLocation“.


<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-3.0.xsd">

	<bean id="XMLConverter" class="com.mkyong.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:mapping.xml" />
	</bean>

</beans>

Test it again, the XML file “customer.xml” will be updated.

File : customer.xml


<?xml version="1.0" encoding="UTF-8"?>
<customer age="30">
	<flag>true</flag>
	<name>mkyong</name>
	<address>This is address</address>
</customer>

Download Source Code

References

  1. Castor XML mapping
  2. Spring Object/XML Mapping reference

About the Author

author image
mkyong
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

avatar
25 Comment threads
6 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
27 Comment authors
Kitabinaya keerthanaMuhammed AbdulRômulo SoratoAnju Sasidaran Recent comment authors
newest oldest most voted
riz
Guest
riz

Hey mkyong,

Thanks for all these awesome tutorials!!

In this example you are reading only one object from XML, but do you know how can I read a collection of customers from an XML file whose structure is as follows:

 <?xml version="1.0" encoding="UTF-8"?>
 <customers>
     <customer age="26"><name>user1</name></customer>
     <customer age="27"><name>user2</name></customer>
 </customers>
@FlavioTroja
Guest
@FlavioTroja

Me too.

@FlavioTroja
Guest
@FlavioTroja
Kit
Guest
Kit

Thank you for your examples. It worked well for me as a static java app. I used the same code above in a Spring app and the converter will throw :
java.lang.IllegalArgumentException: object is not an instance of declaring class… . at java.lang.reflect.Method.invoke(Unknown Source)

I have been trying unsuccessfully to resolve the error. Any ideas how to resolve the unknown source problem?

abinaya keerthana
Guest
abinaya keerthana

Anyone please tell How to do this with Spring 4.2.2 ?

Muhammed Abdul
Guest
Muhammed Abdul

Hi,

How can i define the CastorMarshaller and XMLConverter beans using Annotations in a configuration class?

please help.

Anju Sasidaran
Guest
Anju Sasidaran

Hello, I am trying to read the xml 100000 200000 3% 124324 131523 188195 284100 589320 2.5% 365324 413123 518815 and my mapping file is But it is throwing the error. Could you please help me to format my mapping xml? The mapping for , is not correct .

Yadi Chinchalpet
Guest
Yadi Chinchalpet

I am getting below exception while executing the above example: Exception in thread “main” org.springframework.oxm.UnmarshallingFailureException: Castor unmarshalling exception; nested exception is org.exolab.castor.xml.MarshalException: org.xml.sax.SAXException: The class for the root element ‘customer’ could not be found.{File: [not available]; line: 2; column: 32} at org.springframework.oxm.castor.CastorMarshaller.convertCastorException(CastorMarshaller.java:675) at org.springframework.oxm.castor.CastorMarshaller.unmarshalInputStream(CastorMarshaller.java:564) at org.springframework.oxm.support.AbstractMarshaller.unmarshalStreamSource(AbstractMarshaller.java:368) at org.springframework.oxm.support.AbstractMarshaller.unmarshal(AbstractMarshaller.java:134) at core.XMLConverter.convertFromXMLToObject(XMLConverter.java:73) at action.Execute.main(Execute.java:39) Caused by: org.exolab.castor.xml.MarshalException: org.xml.sax.SAXException: The class for the root element ‘customer’ could not be found.{File: [not available]; line: 2; column: 32} at org.exolab.castor.xml.Unmarshaller.convertSAXExceptionToMarshalException(Unmarshaller.java:919) at org.exolab.castor.xml.Unmarshaller.unmarshal(Unmarshaller.java:775) at org.springframework.oxm.castor.CastorMarshaller.unmarshalInputStream(CastorMarshaller.java:561) … 4 more Caused by: org.xml.sax.SAXException: The class for the root element ‘customer’ could not be found. at org.exolab.castor.xml.UnmarshalHandler.processFirstElement(UnmarshalHandler.java:920) at org.exolab.castor.xml.StartElementProcessor.compute(StartElementProcessor.java:103)… Read more »

Kay Casavant
Guest
Kay Casavant

Thank you again for another helpful tutorial in the java spring and adjacent tech space. Whenever I see a list of resources and your blog comes up I go there first. keep up the good work.

Rimma
Guest
Rimma

Great article! Thank you.

But still I have a small question – I’m new in Spring and I’m using Spring 4. I’d like to use @Autowired and not xml with beans. When I implement your solution, I’ve got an error:

No qualifying bean of type [org.springframework.oxm.Marshaller] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency a nnotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

Can you please tell me what to add? I’ve added some @Component and @Autowired, etc.

Thank you in advance,
Rimma

Rômulo Sorato
Guest
Rômulo Sorato

I´m facing the same problem

Ram
Guest
Ram
frank71
Guest
frank71

Great Tutorial on SpringFramework.
In this tutorial the output file is write on one row unformatted .
I know , it’s xml so it’s the same but in jaxb it’s possible format the output.
In Castor it’s possible do it ?

mak
Guest
mak

Thanks for providing this wonderful tutorial.
I have a one question,I want to generate blank element like in following example

true
mkyong
This is address
How to generate this .
Please help me.
Thanks.

Daniel Chermetz
Guest
Daniel Chermetz

Thank you for this tutorial. It worked well for me.
But It wouldn’t run until I added the mapping.xml and a reference to it in the bean.
I would suggest modifying the tutorial to emphasize that this part needs to be there before testing.

Dirk
Guest
Dirk

Sorry…not Cargo but Castor! ;-) I got that mappings thing solved but I am not able to tell Spring to autowire an XMLConverter instance into my @Service class: org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘circularImporterController’: Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.foo.bar.service.custom.MyImportService com.foo.bar.importer.portlet.MyImporterController.demoImportCircularService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘demoImportService’: Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.foo.bar.utils.XMLConverter com.foo.bar.service.custom.DemoImportServiceImpl.xmlConverter; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.foo.bar.utils.XMLConverter] found for dependency: expected at least 1 bean which qualifies as autowire candidate… Read more »

Dirk
Guest
Dirk

I tried to use Cargo in a portlet project. Whenever I try to startup Liferay I get this exception:

Caused by: java.io.FileNotFoundException: class path resource [mappings.xml] cannot be opened because it does not exist

I tried to create a new folder and add it as a further source folder to the classpath or put mappings.xml in many places in the project. Unsuccessfully.
How can I tell Liferay (or…Spring) to find my mappings. xml?? Neither classpath:mappings.xml nor classpath*:mappings.xml works.

Ramesh
Guest
Ramesh

Thanks .. its very useful for me….

MSzczudlo
Guest
MSzczudlo

Hi!

I have one question.
Is there any way to obtain object serialized to xml as pure string, not to file.
Something like:

String xml = xmlConverter.getAsXml(obj)

Thanks

Abhijit
Guest
Abhijit

What if the xml file is nested?
I mean if customer class has account as object and there is element inside customer in xml file. Could you please suggest how would be the mapping in this particular case??

Saleem S
Guest
Saleem S

Hi mkyong,
I’m getting following error when i run this project,
Exception in thread “main” org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘XMLConverter’ defined in class path resource [App.xml]: Cannot resolve reference to bean ‘castorMarshaller’ while setting bean property ‘marshaller’; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘castorMarshaller’ defined in class path resource [App.xml]: Instantiation of bean failed; nested exception is java.lang.NoClassDefFoundError: org/exolab/castor/xml/XMLException

Santhosh
Guest
Santhosh

Hi Mk,

Using Xtream from codehaus is made easy of conversion xml to object, json etc.
http://xstream.codehaus.org/index.html

Thanks,
Santhosh

Nama
Guest
Nama

Hi, how can I use Castor and Xerces to marshall and unmarshall multiple objects? According to your example, what If i have multiple Customer objects and need multiple customer elements be generated in the XML file? Please advise.

Subhakanta Nanda
Guest
Subhakanta Nanda

Really you have explained very nicely.Thanks a lot :)

Nitin
Guest
Nitin

Nice tutorial but I am not able to resolve the dependent jars . Can you share the settings.xml or repository urls which I can use to get the dependant jars.

trackback
Java XML Binding Marshalling UnMarshaller « Paulo Borges aka poolborges

[…] Spring OXM Example – http://www.mkyong.com/spring3/spring-objectxml-mapping-example/  (GOSTEI) […]

trackback
Spring Tutorial

[…] 3.0, Object to XML mapping (OXM) is moved from the Spring Web Services to the core Spring Framework.Spring Object/XML mapping example Spring oxm + castor, convert Object to XML and vice verse.Spring JDBC SupportSpring provides many […]

sudheer
Guest
sudheer

Hi mkyong,

For the above Spring Object/XML mapping example ,it needs another dependency i.e

javax.xml.stream
com.springsource.javax.xml.stream

1.0.1

or else it showing the errors.

Thanks,

sudheer

Woolley
Guest
Woolley

Hi mkyong,

Spring Object/XML mapping example Compile Fail

?this.unmarshaller.unmarshal(new StreamSource(is));?
Caused by: org.xml.sax.SAXException: The class for the root element ‘customer’ could not be found.

AquaDrehz
Guest
AquaDrehz

This example work fine in Eclipse Juno.
I just need to configure project facet propeties into JBoss maven integration.
After run as Goal: install
Everything work fine.

Hope this help for beginner.