In this post we’ll see how to serialize an object graph to XML (marshalling) and how to deserialize the XML to an object graph (unmarshalling) using Castor and Spring OXM module.
Spring Object-XML mapping support
Spring framework provides support for converting an XML document to/from an object using Spring-OXM module.
Spring-OXM provides abstractions to the O/X mapping frameworks through two interfaces.
- Marshaller
- Unmarshaller
These abstractions allow you to switch O/X mapping frameworks with relative ease, with little or no changes required on the classes that do the marshalling.
The implementation classes provided by Spring-OXM for these interfaces are-
- CastorMarshaller- For object-XML mapping using Castor.
- Jaxb2Marshaller- For object-XML mapping using JAXB. Refer Spring Object XML Mapping Support - JAXB Example to see an example of XML marshalling-unmarshalling in Spring using JAXB.
- JibxMarshaller- For object-XML mapping using JIBX.
Object to XML mapping using Castor – Spring Example
In this example we’ll see how to do XML marshalling and unmarshalling using Castor and Spring-OXM.
Maven dependencies
Along with Spring core dependencies you’ll need following maven dependencies for Castor and Spring-OXM.
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>10</java.version> <spring.version>5.0.8.RELEASE</spring.version> </properties> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-oxm</artifactId> <version>${spring.version}</version> </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>
Bean classes
Two classes are used in this XML marshalling and unmarshalling example, User class whose objects are returned in the XML form and UserListContainer class which contains the List of objects of type User.
User.java
public class User { private int id; private String firstName; private String lastName; private String email; public User() { } public User(int id, String firstName, String lastName, String email) { this.id = id; this.firstName = firstName; this.lastName = lastName; this.email = email; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @Override public String toString() { return "id- " + getId() + " First Name- " + getFirstName() + " Last Name- " + getLastName() + " Email- " + getEmail(); } }
UserListContainer.java
public class UserListContainer { private List<User> userList; public List<User> getUserList() { return userList; } public void setUserList(List<User> userList) { this.userList = userList; } }
Spring XML Configuration for CastorMarshaller
<?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:context="http://www.springframework.org/schema/context" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/task http://www.springframework.org/task/spring-task.xsd"> <bean id="castorMarshaller" class="org.springframework.oxm.castor.CastorMarshaller"> <property name="targetPackage" value="org.netjs.model" /> <property name="mappingLocation" value="classpath:mapping.xml" /> </bean> <bean id="objXmlmapper" class="org.netjs.service.ObjXMLMapper"> <property name="marshaller" ref="castorMarshaller" /> <property name="unmarshaller" ref="castorMarshaller" /> </bean> </beans>
With CastorMarshaller bean you can define the target classes which are used in Marshalling or you can define the package where the POJOs reside.
Mapping information for the object fields to XML element or attribute conversion can be provided using a Castor mapping file that information is provided to the CastorMarshaller bean using the mappingLocation property.
Since CastorMarshaller class implements both the Marshaller and Unmarshaller interfaces so the same bean is provided as reference for both marshaller and unmarshaller properties in ObjXMLMapper bean.
ObjXMLMapper.java
This is the class where marshalling and unmarshalling is done using the CastorMarshaller class in Spring-OXM. In the class Marshaller and Unmarshaller interfaces are used which are set to CastorMarshaller instance using the Spring configuration.public class ObjXMLMapper { private static final String FILE_NAME = "users.xml"; private Marshaller marshaller; private Unmarshaller unmarshaller; public void setMarshaller(Marshaller marshaller) { this.marshaller = marshaller; } public void setUnmarshaller(Unmarshaller unmarshaller) { this.unmarshaller = unmarshaller; } // Converting object graph to XML (marshalling) public void objToXML() throws IOException { // call to get object graph UserListContainer userList = getUsers(); try (FileOutputStream os = new FileOutputStream(FILE_NAME)) { this.marshaller.marshal(userList, new StreamResult(os)); } } // Converting XML to an object graph (unmarshalling) public void XMLToObj() throws IOException { UserListContainer userList = new UserListContainer(); try (FileInputStream is = new FileInputStream(FILE_NAME)) { userList = (UserListContainer)this.unmarshaller.unmarshal(new StreamSource(is)); } userList.getUserList().forEach(System.out::println); } public UserListContainer getUsers(){ List<User> users = getListOfUsers(); UserListContainer userList = new UserListContainer(); userList.setUserList(users); return userList; } // Dummy method for adding List of Users private List<User> getListOfUsers() { List<User> users = new ArrayList<User>(); users.add(new User(1, "Jack", "Reacher", "abc@xyz.com")); users.add(new User(2, "Remington", "Steele", "rs@cbd.com")); users.add(new User(3, "Jonathan", "Raven", "jr@sn.com")); return users; } }
Castor mapping file (Mapping.xml)
In order to have more control over how the object to/from XML conversion happens a mapping file is provided which Castor uses as a reference.
<?xml version="1.0" encoding="UTF-8"?> <mapping> <class name="org.netjs.model.UserListContainer"> <map-to xml="Users" /> <field name="userList" type="org.netjs.model.User" collection="arraylist"> <bind-xml name="user" node="element" /> </field> </class> <class name="org.netjs.model.User"> <field name="id" type="integer"> <bind-xml name="id" node="attribute" /> </field> <field name="firstName" type="string" /> <field name="lastName" type="string" /> <field name="email" type="string" /> </class> </mapping>
Since we want a parent element as Users which holds the list of users so two class definitions are given in castor mapping file. First class definition is for UserListContainer, which tells that the it contains elements of type User in an ArrayList which are to be bound as User element in XML.
Second class definition is for User type, it tells how fields of User are to be mapped.
Class used to run the application
public class App { public static void main( String[] args ){ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext ("appcontext.xml"); ObjXMLMapper objXMLMapper = context.getBean("objXmlmapper", ObjXMLMapper.class); try { objXMLMapper.objToXML(); objXMLMapper.XMLToObj(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } context.close(); } }On running you get the XML as follows after the object graph is serialized to XML-
<?xml version="1.0" encoding="ISO-8859-1"?> <Users> <user id="1"> <first-name>Jack</first-name> <last-name>Reacher</last-name> <email>abc@xyz.com</email> </user> <user id="2"> <first-name>Remington</first-name> <last-name>Steele</last-name> <email>rs@cbd.com</email> </user> <user id="3"> <first-name>Jonathan</first-name> <last-name>Raven</last-name> <email>jr@sn.com</email> </user> </Users>
Deserializing the XML to object graph displays the object fields on the console-
id- 1 First Name- Jack Last Name- Reacher Email- abc@xyz.com id- 2 First Name- Remington Last Name- Steele Email- rs@cbd.com id- 3 First Name- Jonathan Last Name- Raven Email- jr@sn.com
That's all for this topic Spring Object XML Mapping (OXM) Castor Example. If you have any doubt or any suggestions to make please drop a comment. Thanks!
>>>Return to Spring Tutorial Page
Related Topics
You may also like-
No comments:
Post a Comment