How to serialize and deserialize Java Object to XML using Xstream

10984
Mar 20, 2016

Many times we need to convert a Java object to XML string or xml string to object, in that case Xstream is good choice specially if we are working with third party Java classes where we don't have source of class to change.
If a Java object that needs to be converted to XML string, and the code is not available to modify, then we have only few options to choose a tool which can convert object to xml string. Basically in this case we need to provide some metadata (e.g. mappings to class property to xml element name, also sometimes called bindings) to the converter. This meta data can be an external xml file or can be programmatically. Using Xstream we can provide these metadata programmatically.

Lets take some examples. Suppose we have two classed (could be third party) as below

Country.java

package com.groupkt.xstream;

import java.util.List;

public class Country {
private String name;
private String isoCode;
private String currency;
private List states;
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the isoCode
*/
public String getIsoCode() {
return isoCode;
}
/**
* @param isoCode the isoCode to set
*/
public void setIsoCode(String isoCode) {
this.isoCode = isoCode;
}
/**
* @return the currency
*/
public String getCurrency() {
return currency;
}
/**
* @param currency the currency to set
*/
public void setCurrency(String currency) {
this.currency = currency;
}
/**
* @return the states
*/
public List getStates() {
return states;
}
/**
* @param states the states to set
*/
public void setStates(List states) {
this.states = states;
}

@Override
public String toString() {
return new StringBuilder()
.append("name:").append(name)
.append(",isoCode:").append(isoCode)
.append(",currency:").append(currency)
.append(",states:").append(states)
.toString();
}
}


State.java

package com.groupkt.xstream;

public class State {
private String name;
private String capital;

public State(String name, String capital) {
this.name = name;
this.capital = capital;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the capital
*/
public String getCapital() {
return capital;
}
/**
* @param capital the capital to set
*/
public void setCapital(String capital) {
this.capital = capital;
}

@Override
public String toString() {
return new StringBuilder()
.append("name:").append(name)
.append("capital:").append(capital)
.toString();
}
}

and want a xml string from an Country object similar to

<country code="IND">
<name>India</name>
<currency>INR</currency>
<state>
<name>Uttar Pradesh</name>
<capital>Lucknow</capital>
</state>
<state>
<name>Maharashtra</name>
<capital>Mumbai</capital>
</state>
</country>

Step 1. Adding dependency


If working with maven project then add following dependency in pom.xml


<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.7</version>
</dependency>


otherwise download Xstream jar and add to classpath.


Step 2. Create a method to get Xstream object



private static XStream getXstreamObject() {
XStream xstream = new XStream(); // DomDriver and StaxDriver instances also can be used with constructor
return xstream;
}

this method will return an Xstream object which will convert Country object to xml string. lets create a test class to test it

package com.groupkt.xstream;

import java.util.ArrayList;
import java.util.List;

import com.thoughtworks.xstream.XStream;

public class XstreamTest {

public static void main(String[] args) {
Country country = new Country();
country.setName("India");
country.setIsoCode("IND");
country.setCurrency("INR");
List<State> states = new ArrayList<State>();
states.add(new State("Uttar Pradesh", "Lucknow"));
states.add(new State("Maharashtra", "Mumbai"));
country.setStates(states);

XStream xStream = getXstreamObject();

String xml = xStream.toXML(country);

System.out.println("SerializedCountry XML:
"+xml);
}

private static XStream getXstreamObject() {
XStream xstream = new XStream(); // DomDriver and StaxDriver instances also can be used with constructor
return xstream;
}
}
and this will convert the country object similar to

<com.groupkt.xstream.Country>
<name>India</name>
<isoCode>IND</isoCode>
<currency>INR</currency>
<states>
<com.groupkt.xstream.State>
<name>Uttar Pradesh</name>
<capital>Lucknow</capital>
</com.groupkt.xstream.State>
<com.groupkt.xstream.State>
<name>Maharashtra</name>
<capital>Mumbai</capital>
</com.groupkt.xstream.State>
</states>
</com.groupkt.xstream.Country>


Step 3. Configure the Xstream programmatically to get desired xml


now we need to tweak the Xstream to get the desired xml. change the getXstreamObject() method as below

private static XStream getXstreamObject() {
XStream xstream = new XStream(); // DomDriver and StaxDriver instances also can be used with constructor
xstream.alias("country", Country.class); // this will remove the Country class package name
xstream.alias("state", State.class); // this will remove the State class package name
xstream.useAttributeFor(Country.class, "isoCode"); // make the isoCode to attribute from element
xstream.aliasField("code", Country.class, "isoCode"); // change 'isoCode' to code
xstream.addImplicitCollection(Country.class, "states"); // don't want all states inside .
return xstream;
}

and now the final result will be similar to below

<country code="IND">
<name>India</name>
<currency>INR</currency>
<state>
<name>Uttar Pradesh</name>
<capital>Lucknow</capital>
</state>
<state>
<name>Maharashtra</name>
<capital>Mumbai</capital>
</state>
</country>


Step 4. Convert back xml string to Java object


Converting back (deserialization) xml string to Java object is very easy with Xstream. just need to add

Country deSerializedCountry = (Country)xStream.fromXML(xml);

it will return you again object. add following two statements at the end of main method to test it

Country deSerializedCountry = (Country)xStream.fromXML(xml);
System.out.println("DeSerializedCountry Object:
"+deSerializedCountry);


comments powered by Disqus

© Copyright 2017