Main Tutorials

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 Author

author image
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

Subscribe
Notify of
30 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
riz
11 years ago

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
11 years ago
Reply to  riz
@FlavioTroja
11 years ago
Reply to  riz

Me too.

santrupta
1 year ago

how can I convert a xml to a java.util.map without having those entryset, key , value tags in the xml ? Please answer…

Kit
6 years ago

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
7 years ago

Anyone please tell How to do this with Spring 4.2.2 ?

Muhammed Abdul
8 years ago

Hi,

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

please help.

Anju Sasidaran
8 years ago

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
8 years ago

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)

at org.exolab.castor.xml.UnmarshalHandler.startElementProcessing(UnmarshalHandler.java:841)

at org.exolab.castor.xml.UnmarshalHandler.startElement(UnmarshalHandler.java:766)

at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown Source)

at org.apache.xerces.impl.dtd.XMLDTDValidator.startElement(Unknown Source)

at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanStartElement(Unknown Source)

at org.apache.xerces.impl.XMLDocumentScannerImpl$ContentDispatcher.scanRootElementHook(Unknown Source)

at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)

at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)

at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)

at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)

at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)

at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)

at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)

at org.exolab.castor.xml.Unmarshaller.unmarshal(Unmarshaller.java:763)

… 5 more

Please help me.

Kay Casavant
9 years ago

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
9 years ago

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
8 years ago
Reply to  Rimma

I´m facing the same problem

Ram
9 years ago

can u please update this link http://www.castor.org/xml-mapping.html%20target=

frank71
9 years ago

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
9 years ago

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
9 years ago

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
10 years ago

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 for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

What is missing…or misconfigured? In my WEB-INF/lib/ folder I have placed:
castor-1.3.jar
castor-1.3-core.jar
xercesImpl.jar (ver 2.11.0)
xml-apis.jar (was included in xerces-bin.zip)

I am in a Liferay 6.1.3 and Spring MVC Portlet environment and have to use ANT not Maven!

I hope anyone can help me soon. Thank you.

Dirk
10 years ago

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
10 years ago

Thanks .. its very useful for me….

MSzczudlo
10 years ago

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
10 years ago

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
10 years ago

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
10 years ago

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
10 years ago

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
11 years ago

Really you have explained very nicely.Thanks a lot 🙂

Nitin
11 years ago

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.

sudheer
12 years ago

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

AquaDrehz
11 years ago
Reply to  sudheer

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.

Woolley
11 years ago
Reply to  sudheer

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.