Вы находитесь на странице: 1из 21

Serializing Java Objects using

Xstream
Author: Angelin

Introduction
XStream is a lightweight and easy-to-use open source Java™ library
used for
serializing objects into XML and deserializing XML back into objects. It uses
reflection API to do this.
XStream is a serialization tool and not a data binding tool, which
means that it
does not generate a Java source code file from a DTD or XML Schema
Definition
(XSD) file. The Java classes that are to be serialized needs to be written
such that its
fields would map to the elements of the XML that you wish to read. Even
though
XStream can be defined as a serialization library, the classes that you
want to
serialize need not implement the Serializable marker interface.
Xstream uses a converter-based design for converting certain
known types
such as primitives, String, File, Collections, arrays, and Dates, to and from
XML. For
other objects, reflection is used to serialize each field recursively. Xstream
can
serialize object graphs which are nested.

Initializing Xstream
To use XStream, simply instantiate the XStream class:
XStream xstream = new XStream();
You require xstream-[version].jar and xpp3-[version].jar in the classpath.
XPP3 is a
very fast XML pull-parser implementation. If you do not want to include
this
dependency, you can use a standard JAXP DOM parser instead:
XStream xstream = new XStream(new DomDriver());
// does not require XPP3 library

Serialization and Deserialization


To Serialize an object to a XML String use:
xstream.toXML(Object obj);
To Deserialize an object from an XML String use:
xstream.fromXML(String xml);

A Simple Serialization Program


import com.thoughtworks.xstream.XStream;
public class HelloWorld {
public static void main(String[] args) {
XStream xstream = new XStream();
String salutation = "Hello, World!";
String xml = xstream.toXML(salutation);
System.out.print(xml);
}
}

Output
<string>Hello, World!</string>
The program uses XStream to output a string in XML. The public class
HelloWorld
imports only one class, com.thoughtworks.xstream.XStream. It calls a
constructor for
XStream, creating the object xstream. Then it uses the toXML method to
store the
string salutation as XML, and writes the XML to the console using the
System.out.print method.
XStream automatically wraps the Java String salutation in the XML
element string.
The string element appears to be an example of XStream's style of XML
reflection.

Sample Program for object serialization and deserialization


TestXstream.java
package com.example;
import com.thoughtworks.xstream.XStream;
public class TestXstream {
public static void main(String[] args) {
XStream xstream = new XStream();
Person joe = new Person("Joe", 23);
joe.setPhone(new PhoneNumber(123,"123456"));
joe.setFax(new PhoneNumber(123,"112233"));
//Convert a Java object to XML
String xml = xstream.toXML(joe);
System.out.println(xml);
//Convert XML to a Java object
Person tom = (Person) xstream.fromXML(xml);
System.out.println(tom);
}
}

Person.java
package com.example;
public class Person {
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
private String name;
private int age;
private PhoneNumber phone;
private PhoneNumber fax;
public PhoneNumber getPhone() {
return phone;
}
public void setPhone(PhoneNumber phone) {
this.phone = phone;
}
public PhoneNumber getFax() {
return fax;
}
public void setFax(PhoneNumber fax) {
this.fax = fax;
}
public String toString() {
return "\nName: " + name + "\nAge: " + age + "\nPhone:" + phone
+ "\nFax:" + fax;
}
}

PhoneNumber.java
package com.example;
public class PhoneNumber {
private int code;
private String number;
public PhoneNumber(int code, String number) {
super();
this.code = code;
this.number = number;
}
public String toString() {
return code + "-" + number;
}
}

Output
<com.example.Person>
<name>Joe</name>
<age>23</age>
<phone>
<code>123</code>
<number>123456</number>
</phone>
<fax>
<code>123</code>
<number>112233</number>
</fax>
</com.example.Person>

Name: Joe
Age: 23
Phone:123-123456
Fax:123-112233

The public class TestXstream imports only one class,


com.thoughtworks.xstream.XStream. It calls a constructor for XStream,
creating the
object xstream. Then it uses the toXML method to convert the Person
object to its
XML representation and writes the XML to the console using the
System.out.println
method. Then it uses the fromXML method to convert the string xml back
to an object
(also casting it as Person) and using the overridden toString() method of
the Person
class, a textual representation of the Person object is obtained and printed
to the
console using the System.out.println method.

Tweaking output using alias names


Aliasing enables us to use different tag or attribute names in the
generated XML. The different types of aliasing that Xstream supports are:
• Class aliasing
• Field aliasing
• Attribute aliasing
• Package aliasing
• Omitting fields and root tag of collection

Class aliasing
When Xstream generates xml element corresponding to the class, it by
default uses the fully qualified class name for the element name, including
the
package name.For example, <com.example.Person>. If you need only the
class name (without the package name) as the XML element name, you
have
to use XStream Aliases.

To create alias for any class' name, use


xstream.alias(String alias, Class cls);

For e.g. adding the line,


xstream.alias("Person", Person.class);
produces the following XML:
<Person>
<name>Joe</name>
<age>23</age>
<phone>
<code>123</code>
<number>123456</number>
</phone>
<fax>
<code>123</code>
<number>112233</number>
</fax>
</Person>

Field aliasing
To create an alias for any field (i.e., class member), use
xstream.aliasField(String alias, Class definedIn, String fieldName);
For e.g. adding the line,
xstream.aliasField("Name", Person.class, "name");
produces the following XML:
<Person>
<Name>Joe</Name>
<age>23</age>
<phone>
<code>123</code>
<number>123456</number>
</phone>
<fax>
<code>123</code>
<number>112233</number>
</fax>
</Person>

Attribute aliasing
A primitive field can be made as an attribute instead of a child element,
using
the useAttributeFor() methods. The method signature of one of the
useAttributeFor() methods is given below:
xstream.useAttributeFor(Class definedIn, String fieldName);
Then, using the aliasField() method an alias can be defined for this
attribute.
For e.g. adding the lines,
xstream.useAttributeFor(PhoneNumber.class, "code");
xstream.aliasField("AreaCode", PhoneNumber.class, "code");
xstream.useAttributeFor(PhoneNumber.class, "number");
xstream.aliasField("Number", PhoneNumber.class, "number");
makes the code and number fields of the PhoneNumber class appear as
attributes
with new alias names 'AreaCode' and 'Number' respectively and produces
the
following XML:
<Person>
<Name>Joe</Name>
<age>23</age>
<phone AreaCode="123" Number="123456"/>
<fax AreaCode="123" Number="112233"/>
</Person>
Alternately, aliasAttribute() method can be used to define a field to appear
as
an attribute and give an alias name for it. The method signature of one of
the
useAttributeFor() methods is given below:

xstream.aliasAttribute(Class definedIn, String fieldName, String


alias);

The same output can be obtained by using the following code:


xstream.aliasAttribute(PhoneNumber.class, "code", "AreaCode");
xstream.aliasAttribute(PhoneNumber.class, "number", "Number");

Objects that can be represented as simple string value can be written as


attributes. Such classes have to implement SingleValueConverter, for
converting that Object to String and vice versa.

To demonstrate this, let us add one more class to hold the details of the
Company to which the Person belongs and make this Company
information
appear as an attribute of the Person tag.

Following is the complete listing of the code to do this:


Person.java
package com.example;
public class Person {
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
private String name;
private int age;
private Company company;
private PhoneNumber phone;
private PhoneNumber fax;
public PhoneNumber getPhone() {
return phone;
}
public void setPhone(PhoneNumber phone) {
this.phone = phone;
}
public PhoneNumber getFax() {
return fax;
}
public void setFax(PhoneNumber fax) {
this.fax = fax;
}
public Company getCompany() {
return company;
}
public void setCompany(Company company) {
this.company = company;
}
}

PhoneNumber.java

package com.example;
public class PhoneNumber {
private int code;
private String number;
public PhoneNumber(int code, String number) {
super();
this.code = code;
this.number = number;
}
}
Company.java

package com.example;
public class Company {
private String name;
public Company(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
}

CompanyConverter.java

package com.example;
import com.thoughtworks.xstream.converters.SingleValueConverter;
/**
* Single value converter, responsible for converting String to Company
and vice
* versa
*
*/
public class CompanyConverter implements SingleValueConverter {
/**
* This method is used to extract a String from the given Object
*/
public String toString(Object obj) {
return ((Company) obj).getName();
}
/**
* This method takes a String and returns an Object
*/
public Object fromString(String name) {
return new Company(name);
}
/**
* This method tells XStream which types it can deal with
*/
public boolean canConvert(Class type) {
return type.equals(Company.class);
}
}

TestXstream.java

package com.example;
import com.thoughtworks.xstream.XStream;
public class TestXstream {
public static void main(String[] args) {
XStream xstream = new XStream();
Person joe = new Person("Joe", 23);
joe.setPhone(new PhoneNumber(123,"123456"));
joe.setFax(new PhoneNumber(123,"112233"));
joe.setCompany(new Company("XYZ"));
xstream.alias("Person", Person.class);
xstream.aliasAttribute(Person.class, "company", "Company");
//Register the converter
xstream.registerConverter(new CompanyConverter());
//Convert a Java object to XML
String xml = xstream.toXML(joe);
System.out.println(xml);
}
}

Output
<Person Company="XYZ">
<name>Joe</name>
<age>23</age>
<phone>
<code>123</code>
<number>123456</number>
</phone>
<fax>
<code>123</code>
<number>112233</number>
</fax>
</Person>

Package aliasing
Package aliases can be used to change the package name that
appears in the element name of the generated XML for the class name.

To create alias for any package name, use


xstream.aliasPackage(String alias, String packageName);
For e.g. adding the line,
xstream.aliasPackage("my.company", "com.example");
produces the following XML:
<my.company.Person Company="XYZ">
<name>Joe</name>
<age>23</age>
<phone>
<code>123</code>
<number>123456</number>
</phone>
<fax>
<code>123</code>
<number>112233</number>
</fax>
</my.company.Person>

Omitting fields and root tag of collection


It is possible to omit fields from being serialised. This can be done by
either making it
transient or using the method,
xstream.omitField(Class definedIn, String fieldName)
If a class has a field that is a collection, by default all elements of that
collection are
embedded in an element that represents the collection itself. By
configuring the
XStream with the XStream.addImplicitCollection() methods it is possible to
keep the
elements directly as child of the class and the surrounding tag for the
collection is
omitted. It is even possible to declare more than one implicit collection for
a class, but
the elements must be distinguishable to populate the different collections
correctly at
deserialization.

Let us define one more class called Customers to demonstrate these.

Customers.java

package com.example;
import java.util.List;
public class Customers {
private List customers;
/**
* @param customers the customers to set
*/
public void setCustomers(List customers) {
this.customers = customers;
}
}

Now let us modify the TestXstream class to serialise this class.

TestXstream.java

package com.example;
import java.util.ArrayList;
import com.thoughtworks.xstream.XStream;
public class TestXstream {
public static void main(String[] args) {
XStream xstream = new XStream();
ArrayList persons = new ArrayList();
Person joe = new Person("Joe", 23);
joe.setPhone(new PhoneNumber(123, "123456"));
joe.setFax(new PhoneNumber(123, "112233"));
joe.setCompany(new Company("XYZ"));
Person jack = new Person("Jack", 23);
jack.setPhone(new PhoneNumber(321, "654321"));
jack.setFax(new PhoneNumber(321, "111111"));
jack.setCompany(new Company("ABC"));
persons.add(joe);
persons.add(jack);
Customers customers = new Customers();
customers.setCustomers(persons);
xstream.alias("Person", Person.class);
xstream.aliasAttribute(Person.class, "company", "Company");
//Register the converter
xstream.registerConverter(new CompanyConverter());
//Omit the phone and fax field information from the resulting XML
xstream.omitField(Person.class, "phone");
xstream.omitField(Person.class, "fax");
//Set alias name for Customers class
xstream.alias("Customers", Customers.class);
//Convert a Java object to XML
String xml = xstream.toXML(customers);
System.out.println(xml);
//Omit the container element representing the list of customers
xstream.addImplicitCollection(Customers.class, "customers");
//Convert a Java object to XML
xml = xstream.toXML(customers);
System.out.println("\nAfter omitting the container tag of the
collection:");
System.out.println(xml);
}
}

Output
<Customers>
<customers>
<Person Company="XYZ">
<name>Joe</name>
<age>23</age>
</Person>
<Person Company="ABC">
<name>Jack</name>
<age>23</age>
</Person>
</customers>
</Customers>

After omitting the container tag of the collection:


<Customers>
<Person Company="XYZ">
<name>Joe</name>
<age>23</age>
</Person>
<Person Company="ABC">
<name>Jack</name>
<age>23</age>
</Person>
</Customers>

Annotations
Annotations simplifies the process of setting aliases and registering
converters etc.
The table below shows the different annotation types supported by
Xstream.
Annotation Types Description
XStreamAlias Annotation used to define an XStream class or field value.
XStreamAsAttribute Defines that a field should be serialized as an
attribute.
XStreamConverter Annotation to declare a converter.
XStreamImplicit An annotation for marking a field as an implicit
collection.
XStreamInclude Annotation to force automated processing of further
classes.
XStreamOmitField Declares a field to be omitted.
Now let us see how we can use annotations instead of the Xstream
methods that we
had used in the sample codes in the previous section on tweaking output
using alias
names

• @XstreamAlias
Instead of using the following statement to set an alias name for the class
Person:
xstream.alias("Person", Person.class);
the @XStreamAlias annotation can be written in the class Person as shown
below:

@XStreamAlias("Person")
public class Person {
...
...
}

Similarly, instead of the statement:


xstream.alias("Customers", Customers.class);
the @XStreamAlias annotation can be written in the class Customers as
shown below:

@XStreamAlias("Customers")
public class Customers {
...
...
}

• @XstreamAsAttribute
Instead of using the following statement to make the member variable
company defined in the Person class appear as an attribute of the Person
tag
and creating an alias for it:
xstream.aliasAttribute(Person.class, "company", "Company");
the @XStreamAlias annotations can be written in the class Person as
shown
below:
@XStreamAlias("Person")
public class Person {
...
...
@XStreamAsAttribute
@XStreamAlias("Company")
private Company company;
...
...
}
• @XStreamConverter
Instead of using the following statement to register a converter for the
class
Company:
xstream.registerConverter(new CompanyConverter());
the @XStreamConverter annotation can be written in the class Company
as
shown below:
@XStreamConverter(CompanyConverter.class)
public class Company {
...
...
}
To register the custom converter locally, i.e. only for the member variable
company defined in the Person class, the @XStreamConverter annotation
should be written in the class Person as shown below:
@XStreamAlias("Person")
public class Person {
...
... @XStreamAsAttribute
@XstreamAlias("Company")
@XStreamConverter(CompanyConverter.class)
private Company company;
...
...
}

• @XStreamOmitField
Instead of using the following statements to omit fields from the
serialization
process:
xstream.omitField(Person.class, "phone");
xstream.omitField(Person.class, "fax");
the @XStreamOmitField annotation can be written in the class Person as
shown below:
@XStreamAlias("Person")
public class Person {
...
@XStreamOmitField
private PhoneNumber phone;
@XStreamOmitField
private PhoneNumber fax;
...
}

• @XStreamImplicit
Instead of using the following statement to omit the container element
representing the list of customers:
xstream.addImplicitCollection(Customers.class, "customers");
the @XStreamImplicit annotation can be written in the class Customers as
shown below:
@XStreamAlias("Customers")
public class Customers {
@XStreamImplicit
private List customers;
...
...
}
The code of the Person class, Company class and the Customers class,
updated
with annotations is given below.

Person.java

package com.example;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.annotations.XStreamConverter;
import com.thoughtworks.xstream.annotations.XStreamOmitField;
@XStreamAlias("Person")
public class Person {
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}

private String name;


private int age;
@XStreamAsAttribute
@XStreamAlias("Company")
private Company company;
@XStreamOmitField
private PhoneNumber phone;
@XStreamOmitField
private PhoneNumber fax;
public PhoneNumber getPhone() {
return phone;
}
public void setPhone(PhoneNumber phone) {
this.phone = phone;
}
public PhoneNumber getFax() {
return fax;
}
public void setFax(PhoneNumber fax) {
this.fax = fax;
}
public Company getCompany() {
return company;
}
public void setCompany(Company company) {
this.company = company;
}
}

Company.java

package com.example;
@XStreamConverter(CompanyConverter.class)
public class Company {
private String name;
public Company(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
}

Customers.java

package com.example;
import java.util.List;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamImplicit;
@XStreamAlias("Customers")
public class Customers {
@XStreamImplicit
private List customers;
/**
* @param customers
* the customers to set
*/
public void setCustomers(List customers) {
this.customers = customers;
}
}

Now after using these annotations, the TestXstream class is simplified as


given
below. XStream's processAnnotation() method is called to configure the
XStream
instance with the annotations present in the different classes. If you let
XStream
process the annotations of a type, it will also process all annotations of the
related
types i.e. all super types, implemented interfaces, the class types of the
members
and all their generic types. For e.g. in the code given below, the statement
xstream.processAnnotations(Person.class);
will also process the annotations of its member of type Company. So there
is no
need to explicitly configure processAnnotation() for the class Company.
TestXstream.java

package com.example;
import java.util.ArrayList;
import com.thoughtworks.xstream.XStream;
public class TestXstream {
public static void main(String[] args) {
XStream xstream = new XStream();
ArrayList persons = new ArrayList();
Person joe = new Person("Joe", 23);
joe.setPhone(new PhoneNumber(123, "123456"));
joe.setFax(new PhoneNumber(123, "112233"));
joe.setCompany(new Company("XYZ"));
Person jack = new Person("Jack", 23);
jack.setPhone(new PhoneNumber(321, "654321"));
jack.setFax(new PhoneNumber(321, "111111"));
jack.setCompany(new Company("ABC"));
persons.add(joe);
persons.add(jack);

Customers customers = new Customers();


customers.setCustomers(persons);
//Convert a Java object to XML
String xml = xstream.toXML(customers);
System.out.println("Serialized XML generated when the annotations
were not processed:");
System.out.println(xml);
//Call processAnnotation method to configure the XStream instance
//with the annotations present in the different classes
xstream.processAnnotations(Person.class);
xstream.processAnnotations(Customers.class);
//Convert a Java object to XML
xml = xstream.toXML(customers);
System.out.println("\nSerialized XML generated after processing the
annotations:");
System.out.println(xml);
}
}

Output
Serialized XML generated when the annotations were not processed:
<com.example.Customers>
<customers>
<com.example.Person>
<name>Joe</name>
<age>23</age>
<company>
<name>XYZ</name>
</company>
<phone>
<code>123</code>
<number>123456</number>
</phone>
<fax>
<code>123</code>
<number>112233</number>
</fax>
</com.example.Person>
<com.example.Person>
<name>Jack</name>
<age>23</age>
<company>
<name>ABC</name>
</company>
<phone>
<code>321</code>
<number>654321</number>
</phone>
<fax>
<code>321</code>
<number>111111</number>
</fax>
</com.example.Person>
</customers>
</com.example.Customers>
Serialized XML generated after processing the annotations:
<Customers>
<Person Company="XYZ">
<name>Joe</name>
<age>23</age>
</Person>
<Person Company="ABC">
<name>Jack</name>
<age>23</age>
</Person>
</Customers>

Converters
The responsibility of a Converter is to provide a strategy for
converting
particular types of objects found in the object graph, to and from XML.
XStream
provides Converters for common types such as primitives, String, File,
Collections,
arrays, and Dates.

Two types of converters provided by Xstream are:

• Converters for common basic types in Java.


These convert the item into a single String, with no nested elements.
For e.g.,
import java.util.Date;
import com.thoughtworks.xstream.XStream;
public class HelloWorld {
public static void main(String[] args) {
XStream xstream = new XStream();
Date timeNow = new Date(System.currentTimeMillis());
String xml = xstream.toXML(timeNow);
System.out.print(xml);
}
}
Output
<date>2009-09-11 00:09:23.737 IST</date>

Here, XStream converts the date value into String and automatically
wraps
the Date object into its XML element representation <date>.

• Converters for collections – collections such as arrays, Lists, Sets and


Maps write
their items as nested elements.
For e.g., the output of the following code shows how maps and arrays are
serialised.
import java.util.HashMap;
import com.thoughtworks.xstream.XStream;
public class HelloWorld {
public static void main(String[] args) {
XStream xstream = new XStream();
HashMap stdCodes = new HashMap();
stdCodes.put("Delhi", "011");
stdCodes.put("Mumbai", "022");
stdCodes.put("Kolkatta", "033");
stdCodes.put("Chennai", "044");
String xml = xstream.toXML(stdCodes);
System.out.println(xml);
String continents[] = new String[7];
continents[0] = "Asia";
continents[1] = "Africa";
continents[2] = "Australia";
continents[3] = "Europe";
continents[4] = "Antartica";
continents[5] = "North America";
continents[6] = "South America";
xml = xstream.toXML(continents);
System.out.println("\n" + xml);
}
}
Output
<map>
<entry>
<string>Mumbai</string>
<string>022</string>
</entry>
<entry>
<string>Kolkatta</string>
<string>033</string>
</entry>
<entry>
<string>Chennai</string>
<string>044</string>
</entry>
<entry>
<string>Delhi</string>
<string>011</string>
</entry>
</map>
<string-array>
<string>Asia</string>
<string>Africa</string>
<string>Australia</string>
<string>Europe</string>
<string>Antartica</string>
<string>North America</string>
<string>South America</string>
</string-array>

Custom converters
Custom converters can be written to customize the information being
serialised or
deserialised. They can be implemented and registered using the
XStream.registerConverter() method.
Converters for objects that can store all information in a single value
should
implement SingleValueConverter.
This can be understood using the folowing example. Let us modify the
Company
class and its custom converter class CompanyConverter that were earlier
given in
the section 'Omitting fields and root tag of collection'.

Company.java

package com.example;
public class Company {
private String name;
private String address;
public Company(String name) {
super();
this.name = name;
}
public Company(String name, String address) {
super();
this.name = name;
this.address = address;
}
public String getName() {
return name;
}
public String getAddress() {
return address;
}
}

CompanyConverter.java
package com.example;
import com.thoughtworks.xstream.converters.SingleValueConverter;
/**
* Single value converter, responsible for converting String to Company
and vice
* versa
*
*/
public class CompanyConverter implements SingleValueConverter {
/**
* This method is used to extract a String from the given Object
*/
public String toString(Object obj) {
return ((Company) obj).getName() + " located at "
+ ((Company) obj).getAddress();
}
/**
* This method takes a String and returns an Object
*/
public Object fromString(String name) {
return new Company(name);
}
/**
* This method tells XStream which types it can deal with
*/
public boolean canConvert(Class type) {
return type.equals(Company.class);
}
}

The following code will demonstrate the use of custom converters.:

ConverterExample.java

package com.example;
import com.thoughtworks.xstream.XStream;
public class ConverterExample {
public static void main(String[] args) {
XStream xstream = new XStream();
Company company = new Company("XYZ");
xstream.alias("Company", Company.class);
//Without using the CompanyConverter
String xml = xstream.toXML(company);
System.out.println("Without using the CompanyConverter:\n" + xml);
//Using the CompanyConverter
xstream.registerConverter(new CompanyConverter());
xml = xstream.toXML(company);
System.out.println("\nUsing the CompanyConverter:\n" + xml);
}
}

Output

Without using the CompanyConverter:


<Company>
<name>XYZ</name>
<address>India</address>
</Company>
Using the CompanyConverter:
<Company>XYZ located at India</Company>

Features
• Ease of use - A high level facade is supplied that simplifies common
use cases.
• No mappings required - Custom objects can be serialized without
need for
specifying mappings.
• Performance - Speed and low memory footprint are a crucial part of
the design,
making it suitable for large object graphs or systems with high message
throughput.
• Clean XML - No information is duplicated that can be obtained via
reflection. This
results in XML that is easier to read for humans and more compact than
native Java
serialization.
• Requires no modifications to objects - Serializes internal fields,
including private
and final. Supports non-public and inner classes. Classes are not required
to have
default constructor.XStream doesn't care about the visibility of the fields
of the
class being serialized/deserialized. No getter and setter methods are
required for
the fields of the class to be serialized/deserialized.
• Full object graph support - Duplicate references encountered in the
objectmodel
will be maintained. Supports circular references.
• Integrates with other XML APIs - By implementing an interface,
XStream can
serialize directly to/from any tree structure (not just XML).
• Customizable conversion stategies - Strategies can be registered
allowing
customization of how particular types are represented as XML.
• Error messages - When an exception occurs due to malformed XML,
detailed
diagnostics are provided to help isolate and fix the problem.
• Thread safe - Once the XStream instance has been created and
configured,
it may be shared across multiple threads allowing objects to be
serialized/deserialized concurrently. Note, that this only applies if
annotations are not auto-detected on-the-fly.
• Interoperability, Robustness and Extensibility

Limitations
• If you are using a JDK prior to 1.4x you must provide a no-argument
default
constructor in order to deserialize objects and instantiate them correctly.
• Auto-detection of annotations may cause race conditions. Preprocessing
annotations is safe though.

Typical Uses
• Data transport
• Object persistence
• Configuration
• Unit Tests

Conclusion
XStream is a fast and easy-to-use Java serialization tool that helps
in serializing
objects into XML and deserializing XML back into objects. It is simpler and
requires
less configuration.

XStream's toXML() method is used for serialization, i.e. to convert


an object to XML. And XStream's fromXML() method is used for
deserialization, i.e. to convert an XML to an object.

The output XML generated by XStream can be customized to have


different tag names, exclude fields, exclude container names for
collections, etc. Tag names of class, field and package can be changed by
setting aliases for them. Fields can be
written as attributes if the field type is handled by a SingleValueConverter
and aliases
can be set for those attributes also.
Converters are used for converting particular types of objects found
in the object graph, to and from XML. Annotations provided by Xstream
make configuration
easier.

References
http://xstream.codehaus.org

Вам также может понравиться