XStream - Quick Guide



XStream - Overview

XStream is a simple Java-based library to serialize Java objects to XML and vice versa.

Features

  • Easy to use − XStream API provides a high-level facade to simplify common use cases.

  • No need to create mapping − XStream API provides default mapping for most of the objects to be serialized.

  • Performance − XStream is fast and is of low memory footprint, which is suitable for large object graphs or systems.

  • Clean XML − XStream produces clean and compact XML output that is easy to read.

  • Object modification not required − XStream serializes internal fields like private and final fields, and supports non-public and inner classes. Default constructor is not a mandatory requirement.

  • Full object graph support − XStream allows to maintain duplicate references encountered in the object-model and also supports circular references.

  • Customizable conversion strategies − Custom strategies can be registered in order to allow customization of a particular type to be represented as XML.

  • Security framework − XStream provides a fair control over unmarshalled types to prevent security issues with manipulated input.

  • Error messages − When an exception occurs due to malformed XML, it provides detailed diagnostics to fix the problem.

  • Alternative output format − XStream supports other output formats like JSON and morphing.

Common Uses

  • Transport − XML is a text representation of object and can be used to transport objects over the wire independent of the serialization / deserialization techniques used.

  • Persistence − Objects can be persisted as XML in databases and can be marshalled/unmarshalled as and when required.

  • Configuration − XML is self-explanatory and is heavily used to define configurations. Objects can also be used for configuration purpose after converting them to XML representation.

  • Unit Tests − XStream API is JUnit compatible and can be used to enhance unit testing of application modules.

XStream - Environment Setup

This chapter will guide you on how to prepare a development environment to start your work with XStream Capabilities. It will also teach you how to set up JDK on your machine before you set up XStream −

Setup Java Development Kit (JDK)

You can download the latest version of SDK from Oracle's Java site − Java SE Downloads. You will find instructions for installing JDK in downloaded files, follow the given instructions to install and configure the setup. Finally set PATH and JAVA_HOME environment variables to refer to the directory that contains java and javac, typically java_install_dir/bin and java_install_dir respectively.

If you are running Windows and have installed the JDK in C:\jdk-24, you would have to put the following line in your C:\autoexec.bat file.

set PATH=C:\jdk-24;%PATH% 
set JAVA_HOME=C:\jdk-24

Alternatively, on Windows NT/2000/XP, you will have to right-click on My Computer, select Properties → Advanced → Environment Variables. Then, you will have to update the PATH value and click the OK button.

On Unix (Solaris, Linux, etc.), if the SDK is installed in /usr/local/jdk-24 and you use the C shell, you will have to put the following into your .cshrc file.

setenv PATH /usr/local/jdk-24/bin:$PATH 
setenv JAVA_HOME /usr/local/jdk-24

Alternatively, if you use an Integrated Development Environment (IDE) like Borland JBuilder, Eclipse, IntelliJ IDEA, or Sun ONE Studio, you will have to compile and run a simple program to confirm that the IDE knows where you have installed Java. Otherwise, you will have to carry out a proper setup as given in the document of the IDE.

Popular Java Editors

To write your Java programs, you need a text editor. There are many sophisticated IDEs available in the market. But for now, you can consider one of the following −

  • Notepad − On Windows machine, you can use any simple text editor like Notepad (Recommended for this tutorial), TextPad.

  • Netbeans − It is a Java IDE that is open-source and free, which can be downloaded from www.netbeans.org/index.html.

  • Eclipse − It is also a Java IDE developed by the eclipse open-source community and can be downloaded from www.eclipse.org.

Install Eclipse

In this chapter, we will write examples using Eclipse IDE. Before proceeding with the installation, make sure that you already have Eclipse installed in your system. If not, download and install Eclipse.

For more information on Eclipse, please refer our Eclipse Tutorial

Set Maven

In this tutorial, we are using maven to run and build the XStream based examples. Follow the Maven - Environment Setup to install maven.

pom.xml

Following are the XStream dependency used in this tutorial under pom.xml.

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

XStream - First Application

Before going into the details of the XStream library, let us see an application in action. In this example, we've created Student and Address classes. We will create a student object and then serialize it to an XML String. Then de-serialize the same XML string to obtain the student object back.

XStreamDemo.java

package com.tutorialspoint.xml;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.stream.StreamResult;

import org.xml.sax.InputSource;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.StaxDriver;
import com.thoughtworks.xstream.security.AnyTypePermission;

public class XStreamDemo {

   public static void main(String args[]) {
	   
	   
      XStreamDemo tester = new XStreamDemo();
      XStream xstream = new XStream(new StaxDriver());
      xstream.addPermission(AnyTypePermission.ANY);
      Student student = tester.getStudentDetails();
      
      //Object to XML Conversion
      String xml = xstream.toXML(student);
      System.out.println(formatXml(xml));
      
      //XML to Object Conversion
      Student student1 = (Student)xstream.fromXML(xml);
      System.out.println(student1);
   }
   
   private Student getStudentDetails() {
   
      Student student = new Student();
      student.setFirstName("Mahesh");
      student.setLastName("Parashar");
      student.setRollNo(1);
      student.setClassName("1st");

      Address address = new Address();
      address.setArea("H.No. 16/3, Preet Vihar.");
      address.setCity("Delhi");
      address.setState("Delhi");
      address.setCountry("India");
      address.setPincode(110012);

      student.setAddress(address);
      return student;
   }
   
   public static String formatXml(String xml) {
   
      try {
         Transformer serializer = SAXTransformerFactory.newInstance().newTransformer();
         
         serializer.setOutputProperty(OutputKeys.INDENT, "yes");
         serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
         
         Source xmlSource = new SAXSource(new InputSource(
            new ByteArrayInputStream(xml.getBytes())));
         StreamResult res =  new StreamResult(new ByteArrayOutputStream());            
         
         serializer.transform(xmlSource, res);
         
         return new String(((ByteArrayOutputStream)res.getOutputStream()).toByteArray());
         
      } catch(Exception e) {
         return xml;
      }
   }
}

class Student {
   private int rollNo;
   private String firstName;
   private String lastName;
   private String className;
   private Address address;

   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 int getRollNo() {
      return rollNo;
   }
   
   public void setRollNo(int rollNo) {
      this.rollNo = rollNo;
   }
   
   public String getClassName() {
      return className;
   }
   
   public void setClassName(String className) {
      this.className = className;
   }
   
   public Address getAddress() {
      return address;
   }
   
   public void setAddress(Address address) {
      this.address = address;
   }
   
   public String toString() {
      StringBuilder stringBuilder = new StringBuilder();
      
      stringBuilder.append("Student [ ");
      stringBuilder.append("\nfirstName: ");
      stringBuilder.append(firstName);
      stringBuilder.append("\nlastName: ");
      stringBuilder.append(lastName);
      stringBuilder.append("\nrollNo: ");
      stringBuilder.append(rollNo);
      stringBuilder.append("\nclassName: ");
      stringBuilder.append(className);
      stringBuilder.append("\naddress: ");
      stringBuilder.append(address);
      stringBuilder.append(" ]");
      
      return stringBuilder.toString();
   }
}

class Address {
   private String area;
   private String city;
   private String state;
   private String country;
   private int pincode;

   public String getArea() {
      return area;
   }

   public void setArea(String area) {
      this.area = area;
   }

   public String getCity() {
      return city;
   }

   public void setCity(String city) {
      this.city = city;
   }

   public String getState() {
      return state;
   }

   public void setState(String state) {
      this.state = state;
   }

   public String getCountry() {
      return country;
   }

   public void setCountry(String country) {
      this.country = country;
   }

   public int getPincode() {
      return pincode;
   }

   public void setPincode(int pincode) {
      this.pincode = pincode;
   }

   public String toString() {

      StringBuilder stringBuilder = new StringBuilder();

      stringBuilder.append("\nAddress [ ");
      stringBuilder.append("\narea: ");
      stringBuilder.append(area);
      stringBuilder.append("\ncity: ");
      stringBuilder.append(city);
      stringBuilder.append("\nstate: ");
      stringBuilder.append(state);
      stringBuilder.append("\ncountry: ");
      stringBuilder.append(country);
      stringBuilder.append("\npincode: ");	
      stringBuilder.append(pincode);
      stringBuilder.append(" ]");

      return stringBuilder.toString();
   }
}

Output

Run the code and verify the output −

<?xml version = "1.0" encoding = "UTF-8"?>
<Student>
   <firstName>Mahesh</firstName>
   <lastName>Parashar</lastName>
   <rollNo>1</rollNo>
   <className>1st</className>
   <address>
      <area>H.No. 16/3, Preet Vihar.</area>
      <city>Delhi</city>
      <state>Delhi</state>
      <country>India</country>
      <pincode>110012</pincode>
   </address>
</Student>

Student [ 
   firstName: Mahesh
   lastName: Parashar
   rollNo: 1
   className: 1st
   address: 
   Address [ 
      area: H.No. 16/3, Preet Vihar.
      city: Delhi
      state: Delhi
      country: India
      pincode: 110012
   ] 
]

Steps to Remember

Following are the important steps to be considered here.

Step 1: Create an XStream Object

Create an XStream object by passing it a StaxDriver. StaxDriver uses Stax pull parser (available from java 6) and is a fast xml parser.

XStream xstream = new XStream(new StaxDriver());

Step 2: Add Permission to XStream Object

We are removing all limitations to XStream object to access java objects.

xstream.addPermission(AnyTypePermission.ANY);

Step 3: Serialize the Object to XML

Use toXML() method to get the XML string representation of the object.

//Object to XML Conversion
String xml = xstream.toXML(student);

Step 4: De-serialize XML to Get the Object

Use fromXML() method to get the object from the XML.

//XML to Object Conversion		
Student student1 = (Student)xstream.fromXML(xml);

XStream - Annotations

XStream supports annotations similarly like automatic configuration instead of coding. In the previous chapter, we've seen the following configurations in code.

xstream.alias("student", Student.class);
xstream.alias("note", Note.class);

xstream.useAttributeFor(Student.class, "studentName");
xstream.aliasField("name", Student.class, "studentName");
xstream.addImplicitCollection(Student.class, "notes");

The following code snippet illustrates the use of annotations to do the same work in a much easier way.

@XStreamAlias("student")   //define class level alias
class Student {

   @XStreamAlias("name")   //define field level alias
   @XStreamAsAttribute     //define field as attribute
   private String studentName;
   
   @XStreamImplicit        //define list as an implicit collection
   private List<Note> notes = new ArrayList<Note>();
   
   @XStreamOmitField       //omit a field to not to be a part of XML
   private int type;
}

Example - Usage of Annotations

Let us test the above annotation using XStream.

XStreamTester.java

package com.tutorialspoint.xml;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

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

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.stream.StreamResult;

import org.xml.sax.InputSource;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.annotations.XStreamImplicit;
import com.thoughtworks.xstream.annotations.XStreamOmitField;
import com.thoughtworks.xstream.io.xml.StaxDriver;

public class XStreamTester {

   public static void main(String args[]) {

      XStreamTester tester = new XStreamTester();
      XStream xstream = new XStream(new StaxDriver());
      Student student = tester.getStudentDetails();
      
      xstream.processAnnotations(Student.class);		

      //Object to XML Conversion
      String xml = xstream.toXML(student);
      System.out.println(formatXml(xml));		
   }
   
   private Student getStudentDetails() {
   
      Student student = new Student("Mahesh");
      
      student.addNote(new Note("first","My first assignment."));
      student.addNote(new Note("second","My Second assignment."));
      student.setType(1);
      
      return student;
   }

   public static String formatXml(String xml) {
   
      try {
         Transformer serializer = SAXTransformerFactory.newInstance().newTransformer();
         
         serializer.setOutputProperty(OutputKeys.INDENT, "yes");
         serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
         
         Source xmlSource = new SAXSource(new InputSource(
            new ByteArrayInputStream(xml.getBytes())));
         StreamResult res = new StreamResult(new ByteArrayOutputStream());            
         
         serializer.transform(xmlSource, res);
         
         return new String(((ByteArrayOutputStream)res.getOutputStream()).toByteArray());
         
      } catch(Exception e) {
         return xml;
      }
   }
}

@XStreamAlias("student")
class Student {

   @XStreamAlias("name")
   @XStreamAsAttribute   
   private String studentName;

   @XStreamImplicit
   private List<Note> notes = new ArrayList<Note>();

   public Student(String name) {
      this.studentName = name;
   }

   public void addNote(Note note) {
      notes.add(note);
   }

   public String getName() {
      return studentName;
   }

   public List<Note> getNotes() {
      return notes;
   }
   
   @XStreamOmitField		
   private int type;

   public int getType() {
      return type;
   }

   public void setType(int type) {
      this.type = type;
   }
}

@XStreamAlias("note")
class Note {
   private String title;
   private String description;

   public Note(String title, String description) {
      this.title = title;
      this.description = description;
   }

   public String getTitle() {
      return title;
   }

   public String getDescription() {
      return description;
   }     
}

Output

Verify the output as follows −

<?xml version = "1.0" encoding = "UTF-8"?>
<student name = "Mahesh">
   <note>
      <title>first</title>
      <description>My first assignment.</description>
   </note>

   <note>
      <title>second</title>
      <description>My Second assignment.</description>
   </note>
</student>

In order to instruct the XStream framework to process annotation, you need to add the following command before serializing xml.

xstream.processAnnotations(Student.class);		

Or

xstream.autodetectAnnotations(true);

XStream - Object Streams

XStream provides alternative implementations of java.io.ObjectInputStream and java.io.ObjectOutputStream so that streams of objects can be serialized or deserialized from XML. This is particularly useful when large sets of objects are to be processed, keeping one object in memory at a time.

Syntax: createObjectOutputStream()

ObjectOutputStream objectOutputStream = xstream.createObjectOutputStream(
   new FileOutputStream("test.txt"));

Syntax: createObjectInputStream()

ObjectInputStream objectInputStream = xstream.createObjectInputStream(
   new FileInputStream("test.txt"));

Example - Usage of object streams

Let us now test the code with object streams in XStream.

XStreamDemo.java

package com.tutorialspoint.xml;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.io.xml.StaxDriver;
import com.thoughtworks.xstream.security.AnyTypePermission;

public class XStreamDemo {
   public static void main(String args[]) {
   
      XStreamDemo tester = new XStreamDemo();
      XStream xstream = new XStream(new StaxDriver());
      xstream.addPermission(AnyTypePermission.ANY);
      xstream.autodetectAnnotations(true);
      
      Student student1 = new Student("Mahesh","Parashar");
      Student student2 = new Student("Suresh","Kalra");
      Student student3 = new Student("Ramesh","Kumar");
      Student student4 = new Student("Naresh","Sharma");
      
      try {
      
         ObjectOutputStream objectOutputStream = xstream.createObjectOutputStream(
            new FileOutputStream("test.txt"));
         
         objectOutputStream.writeObject(student1);
         objectOutputStream.writeObject(student2);
         objectOutputStream.writeObject(student3);
         objectOutputStream.writeObject(student4);
         objectOutputStream.writeObject("Hello World");
         
         objectOutputStream.close();
         
         ObjectInputStream objectInputStream = xstream.createObjectInputStream(
            new FileInputStream("test.txt"));
         
         Student student5 = (Student)objectInputStream.readObject();
         Student student6 = (Student)objectInputStream.readObject();
         Student student7 = (Student)objectInputStream.readObject();
         Student student8 = (Student)objectInputStream.readObject();
         
         String text = (String)objectInputStream.readObject();
         
         System.out.println(student5);
         System.out.println(student6);
         System.out.println(student7);
         System.out.println(student8);
         System.out.println(text);
      
      } catch (IOException e) {
         e.printStackTrace();
         
      } catch (ClassNotFoundException e) {
         e.printStackTrace();
      }
   }
}

@XStreamAlias("student")
class Student {

   private String firstName;
   private String lastName;
   
   public Student(String firstName, String lastName) {
      this.firstName = firstName;
      this.lastName = lastName;
   }

   public String getFirstName() {
      return firstName;
   }

   public String getLastName() {
      return lastName;
   }   

   public String toString() {
      return "Student [ firstName: "+firstName+", lastName: "+ lastName+ " ]";
   }	
}

Output

Verify the output as follows −

Student [ firstName: Mahesh, lastName: Parashar ]
Student [ firstName: Suresh, lastName: Kalra ]
Student [ firstName: Ramesh, lastName: Kumar ]
Student [ firstName: Naresh, lastName: Sharma ]
Hello World

Look at the content of the test.txt present at C:\>XStream_WORKSPACE\com\tutorialspoint\xstream folder.

<?xml version = "1.0" ?>
<object-stream>
   <student>
      <firstName>Mahesh</firstName>
      <lastName>Parashar</lastName>
   </student>
   
   <student>
      <firstName>Suresh</firstName>
      <lastName>Kalra</lastName>
   </student>
   
   <student>
      <firstName>Ramesh</firstName>
      <lastName>Kumar</lastName>
   </student>
   
   <student>
      <firstName>Naresh</firstName>
      <lastName>Sharma</lastName>
   </student>
   <string>Hello World</string>
</object-stream>

XStream - Writing JSON using XStream

XStream supports JSON by initializing XStream object with an appropriate driver. XStream currently supports JettisonMappedXmlDriver and JsonHierarchicalStreamDriver.

Example - Writing JSON using XStream

Let us now test the code with json handling in XStream.

XStreamDemo.java

package com.tutorialspoint.xml;

import java.io.Writer;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.json.JsonHierarchicalStreamDriver;
import com.thoughtworks.xstream.io.json.JsonWriter;

public class XStreamDemo {

   public static void main(String args[]) {

      XStreamDemo tester = new XStreamDemo();
      XStream xstream = new XStream(new JsonHierarchicalStreamDriver() {
      
         public HierarchicalStreamWriter createWriter(Writer writer) {
            return new JsonWriter(writer, JsonWriter.DROP_ROOT_MODE);
         }
      });

      Student student = new Student("Mahesh","Parashar");

      xstream.setMode(XStream.NO_REFERENCES);
      xstream.alias("student", Student.class);
      
      System.out.println(xstream.toXML(student));
   }
}

@XStreamAlias("student")
class Student {

   private String firstName;
   private String lastName;

   public Student(String firstName, String lastName) {
      this.firstName = firstName;
      this.lastName = lastName;
   }

   public String getFirstName() {
      return firstName;
   }

   public String getLastName() {
      return lastName;
   }   
	
   public String toString() {
      return "Student [ firstName: "+firstName+", lastName: "+ lastName+ " ]";
   }	
}

Output

Verify the output as follows −

{
   "firstName": "Mahesh",
   "lastName": "Parashar"
}

XStream - Aliasing

Aliasing is a technique to customize the generated XML or to use a particular formatted XML using XStream. Lets suppose the following XML format is to be used to serialize/de-serialize the Student object.

<student name = "Suresh">
   <note>
      <title>first</title>
      <description>My first assignment.</description>
   </note>
   
   <note>
      <title>second</title>
      <description>My second assignment.</description>
   </note>
</student>

Based on the above XML format, let's create model classes.

class Student {
   private String studentName;
   private List<Note> notes = new ArrayList<Note>();
   
   public Student(String name) {
      this.studentName = name;
   }
   
   public void addNote(Note note) {
      notes.add(note);
   }
   
   public String getName() {
      return studentName;
   }
   
   public List<Note> getNotes() {
      return notes;
   }
}

class Note {
   private String title;
   private String description;

   public Note(String title, String description) {
      this.title = title;
      this.description = description;
   }

   public String getTitle() {
      return title;
   }

   public String getDescription() {
      return description;
   }     
}

Example - Aliasing

Let's test the above objects serialization using XStream.

XStreamDemo.java

package com.tutorialspoint.xml;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

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

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.stream.StreamResult;

import org.xml.sax.InputSource;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.StaxDriver;

public class XStreamDemo {
   public static void main(String args[]) {
   
      XStreamDemo tester = new XStreamDemo();
      XStream xstream = new XStream(new StaxDriver());
      Student student = tester.getStudentDetails();
      
      //Object to XML Conversion
      String xml = xstream.toXML(student);
      System.out.println(formatXml(xml));		
   }	

   private Student getStudentDetails() {
   
      Student student = new Student("Mahesh");
      
      student.addNote(new Note("first","My first assignment."));
      student.addNote(new Note("second","My Second assignment."));
      
      return student;
   }

   public static String formatXml(String xml) {
   
      try {
         Transformer serializer = SAXTransformerFactory.newInstance().newTransformer();
         
         serializer.setOutputProperty(OutputKeys.INDENT, "yes");
         serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
         
         Source xmlSource = new SAXSource(new InputSource(
            new ByteArrayInputStream(xml.getBytes())));
         StreamResult res =  new StreamResult(new ByteArrayOutputStream());            
         
         serializer.transform(xmlSource, res);
         
         return new String(((ByteArrayOutputStream)res.getOutputStream()).toByteArray());
         
      } catch(Exception e) {
         return xml;
      }
   }
}

class Student {
   private String studentName;
   private List<Note> notes = new ArrayList<Note>();
   
   public Student(String name) {
      this.studentName = name;
   }
   
   public void addNote(Note note) {
      notes.add(note);
   }
   
   public String getName() {
      return studentName;
   }
   
   public List<Note> getNotes() {
      return notes;
   }
}

class Note {
   private String title;
   private String description;
   
   public Note(String title, String description) {
      this.title = title;
      this.description = description;
   }
   
   public String getTitle() {
      return title;
   }
   
   public String getDescription() {
      return description;
   }     
}

Output

Verify the output as follows −

<?xml version = "1.0" encoding = "UTF-8"?>
<com.tutorialspoint.xstream.Student>
   <studentName>Mahesh</studentName>
   <notes>
      <com.tutorialspoint.xstream.Note>
         <title>first</title>
         <description>My first assignment.</description>
      </com.tutorialspoint.xstream.Note>
      
      <com.tutorialspoint.xstream.Note>
         <title>second</title>
         <description>My Second assignment.</description>
     </com.tutorialspoint.xstream.Note>
   </notes>
</com.tutorialspoint.xstream.Student>

XStream - Class Aliasing

Class aliasing is used to create an alias of a fully qualified name of a class in XML. Let us modify our original example and add the following code to it.

xstream.alias("student", Student.class);
xstream.alias("note", Note.class);

Example - Usage of class aliasing

Let us test the above object's serialization using XStream.

XStreamTester.java

package com.tutorialspoint.xml;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

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

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.stream.StreamResult;

import org.xml.sax.InputSource;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.StaxDriver;

public class XStreamDemo {

   public static void main(String args[]) {
   
      XStreamDemo tester = new XStreamDemo();
      XStream xstream = new XStream(new StaxDriver());
      
      xstream.alias("student", Student.class);
      xstream.alias("note", Note.class);
      
      Student student = tester.getStudentDetails();
      
      //Object to XML Conversion
      String xml = xstream.toXML(student);
      System.out.println(formatXml(xml));		
   }	

   private Student getStudentDetails() {
      Student student = new Student("Mahesh");
      
      student.addNote(new Note("first","My first assignment."));
      student.addNote(new Note("second","My Second assignment."));
      
      return student;
   }

   public static String formatXml(String xml) {
   
      try {
         Transformer serializer = SAXTransformerFactory.newInstance().newTransformer();
         
         serializer.setOutputProperty(OutputKeys.INDENT, "yes");
         serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
         
         Source xmlSource = new SAXSource(new InputSource(
            new ByteArrayInputStream(xml.getBytes())));
         StreamResult res =  new StreamResult(new ByteArrayOutputStream());            
         
         serializer.transform(xmlSource, res);
         
         return new String(((ByteArrayOutputStream)res.getOutputStream()).toByteArray());
         
      } catch(Exception e) {
         return xml;
      }
   }
}

class Student {
   private String studentName;
   private List<Note> notes = new ArrayList<Note>();
   
   public Student(String name) {
      this.studentName = name;
   }
   
   public void addNote(Note note) {
      notes.add(note);
   }
   
   public String getName() {
      return studentName;
   }
   
   public List<Note> getNotes() {
      return notes;
   }
}

class Note {
   private String title;
   private String description;
   
   public Note(String title, String description) {
      this.title = title;
      this.description = description;
   }
   
   public String getTitle() {
      return title;
   }
   
   public String getDescription() {
      return description;
   }     
}

Output

Verify the output as follows −

<?xml version = "1.0" encoding = "UTF-8"?>
<student>
   <studentName>Mahesh</studentName>
   <notes>
      <note>
         <title>first</title>
         <description>My first assignment.</description>
      </note>

      <note>
         <title>second</title>
         <description>My Second assignment.</description>
      </note>
   </notes>
</student>

XStream - Field Aliasing

Field aliasing is used to create an alias of a field in XML. Let us modify our example again and add the following code to it.

xstream.aliasField("studentName", Student.class, "name");

Example - Usage of field Aliasing

Let us test the above object's serialization using XStream.

XStreamTester.java

package com.tutorialspoint.xml;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

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

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.stream.StreamResult;

import org.xml.sax.InputSource;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.StaxDriver;

public class XStreamDemo {
   public static void main(String args[]) {
   
      XStreamDemo tester = new XStreamDemo();
      XStream xstream = new XStream(new StaxDriver());
      
      xstream.alias("student", Student.class);
      xstream.alias("note", Note.class);
      xstream.aliasField("name", Student.class, "studentName");
      
      Student student = tester.getStudentDetails();

      //Object to XML Conversion
      String xml = xstream.toXML(student);
      System.out.println(formatXml(xml));		
   }	

   private Student getStudentDetails() {
      Student student = new Student("Mahesh");
      
      student.addNote(new Note("first","My first assignment."));
      student.addNote(new Note("second","My Second assignment."));
      
      return student;
   }

   public static String formatXml(String xml) {
   
      try {
         Transformer serializer = SAXTransformerFactory.newInstance().newTransformer();
         
         serializer.setOutputProperty(OutputKeys.INDENT, "yes");
         serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");

         Source xmlSource = new SAXSource(new InputSource(
            new ByteArrayInputStream(xml.getBytes())));
         StreamResult res =  new StreamResult(new ByteArrayOutputStream());            

         serializer.transform(xmlSource, res);

         return new String(((ByteArrayOutputStream)res.getOutputStream()).toByteArray());

      } catch(Exception e) {
         return xml;
      }
   }
}

class Student {
   private String studentName;
   private List<Note> notes = new ArrayList<Note>();
   
   public Student(String name) {
      this.studentName = name;
   }

   public void addNote(Note note) {
      notes.add(note);
   }

   public String getName() {
      return studentName;
   }

   public List<Note> getNotes() {
      return notes;
   }
}

class Note {
   private String title;
   private String description;

   public Note(String title, String description) {
      this.title = title;
      this.description = description;
   }

   public String getTitle() {
      return title;
   }

   public String getDescription() {
      return description;
   }     
}

Output

Verify the output as follows −

<?xml version = "1.0" encoding = "UTF-8"?>
<student>
   <name>Mahesh</name>
   <notes>
      <note>
         <title>first</title>
         <description>My first assignment.</description>
      </note>
      
      <note>
         <title>second</title>
         <description>My Second assignment.</description>
      </note>
   </notes>
</student>

XStream - Implicit Collections Aliasing

Implicit collections aliasing is used when a collection is to be represented in XML without displaying the roots. For example, in our case, we need to display each note one by one but not in the notes root node. Let us modify our example again and add the following code to it.

xstream.addImplicitCollection(Student.class, "notes");

Example - Usage of Implicit Collections Aliasing

Let us test the above objects serialization using XStream.

XStreamTester.java

package com.tutorialspoint.xstream;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

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

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.stream.StreamResult;

import org.xml.sax.InputSource;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.StaxDriver;

public class XStreamTester {

   public static void main(String args[]) {
   
      XStreamTester tester = new XStreamTester();
      XStream xstream = new XStream(new StaxDriver());
      
      xstream.alias("student", Student.class);
      xstream.alias("note", Note.class);
      xstream.aliasField("name", Student.class, "studentName");
      xstream.addImplicitCollection(Student.class, "notes");
      
      Student student = tester.getStudentDetails();
      
      //Object to XML Conversion
      String xml = xstream.toXML(student);
      System.out.println(formatXml(xml));		
   }	

   private Student getStudentDetails() {
      Student student = new Student("Mahesh");
      
      student.addNote(new Note("first","My first assignment."));
      student.addNote(new Note("second","My Second assignment."));
      
      return student;
   }

   public static String formatXml(String xml) {
   
      try {
         Transformer serializer = SAXTransformerFactory.newInstance().newTransformer();
         
         serializer.setOutputProperty(OutputKeys.INDENT, "yes");
         serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
         
         Source xmlSource = new SAXSource(new InputSource(
            new ByteArrayInputStream(xml.getBytes())));
         StreamResult res =  new StreamResult(new ByteArrayOutputStream());            
         
         serializer.transform(xmlSource, res);
         
         return new String(((ByteArrayOutputStream)res.getOutputStream()).toByteArray());
         
      } catch(Exception e) {
         return xml;
      }
   }
}

class Student {
   private String studentName;
   private List<Note> notes = new ArrayList<Note>();
   
   public Student(String name) {
      this.studentName = name;
   }
   
   public void addNote(Note note) {
      notes.add(note);
   }
   
   public String getName() {
      return studentName;
   }
   
   public List<Note> getNotes() {
      return notes;
   }
}

class Note {
   private String title;
   private String description;
   
   public Note(String title, String description) {
      this.title = title;
      this.description = description;
   }
   
   public String getTitle() {
      return title;
   }
   
   public String getDescription() {
      return description;
   }     
}

Output

Verify the output as follow −

<?xml version = "1.0" encoding = "UTF-8"?>
<student>
   <name>Mahesh</name>
   <note>
      <title>first</title>
      <description>My first assignment.</description>
   </note>
   
   <note>
      <title>second</title>
      <description>My Second assignment.</description>
   </note>
</student>

XStream - Attribute Aliasing

Attribute aliasing is used to serialize a member variable as an XML attribute. Let us modify our example again and add the following code to it.

xstream.useAttributeFor(Student.class, "studentName");
xstream.aliasField("name", Student.class, "studentName");

Example - Usage of Attribute Aliasing

Let us test the above object's serialization using XStream.

XStreamTester.java

package com.tutorialspoint.xml;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

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

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;

import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.stream.StreamResult;

import org.xml.sax.InputSource;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.StaxDriver;

public class XStreamDemo {

   public static void main(String args[]) {
   
      XStreamDemo tester = new XStreamDemo();
      XStream xstream = new XStream(new StaxDriver());
      
      xstream.alias("student", Student.class);
      xstream.alias("note", Note.class);
      xstream.useAttributeFor(Student.class, "studentName");
      xstream.aliasField("name", Student.class, "studentName");
      xstream.addImplicitCollection(Student.class, "notes");
      
      Student student = tester.getStudentDetails();
      
      //Object to XML Conversion
      String xml = xstream.toXML(student);
      System.out.println(formatXml(xml));		
   }	

   private Student getStudentDetails() {
      Student student = new Student("Mahesh");
      
      student.addNote(new Note("first","My first assignment."));
      student.addNote(new Note("second","My Second assignment."));
      
      return student;
   }

   public static String formatXml(String xml) {
   
      try {
         Transformer serializer = SAXTransformerFactory.newInstance().newTransformer();
         
         serializer.setOutputProperty(OutputKeys.INDENT, "yes");
         serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
         
         Source xmlSource = new SAXSource(new InputSource(
            new ByteArrayInputStream(xml.getBytes())));
         StreamResult res =  new StreamResult(new ByteArrayOutputStream());            
         
         serializer.transform(xmlSource, res);
         
         return new String(((ByteArrayOutputStream)res.getOutputStream()).toByteArray());
         
      } catch(Exception e) {
         return xml;
      }
   }
}

class Student {
   private String studentName;
   private List<Note> notes = new ArrayList<Note>();
   
   public Student(String name) {
      this.studentName = name;
   }
   
   public void addNote(Note note) {
      notes.add(note);
   }
   
   public String getName() {
      return studentName;
   }
   
   public List<Note> getNotes() {
      return notes;
   }
}

class Note {
   private String title;
   private String description;
   
   public Note(String title, String description) {
      this.title = title;
      this.description = description;
   }
   
   public String getTitle() {
      return title;
   }
   
   public String getDescription() {
      return description;
   }     
}

Output

Verify the output as follows −

<?xml version = "1.0" encoding = "UTF-8"?>
<student name = "Mahesh">
   <note>
      <title>first</title>
      <description>My first assignment.</description>
   </note>

   <note>
      <title>second</title>
      <description>My Second assignment.</description>
   </note>
</student>

XStream - Package Aliasing

Package aliasing is used to create an alias of a fully qualified name of a class in XML to a new qualified name. Let us modify our example again and change the following code.

xstream.alias("student", Student.class);
xstream.alias("note", Note.class);

Above code is changed as follows −

xstream.aliasPackage("my.company.xstream", "com.tutorialspoint.xstream");

Example - Usage of Package aliasing

Let us test the above object's serialization using XStream.

XStreamDemo.java

package com.tutorialspoint.xml;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.stream.StreamResult;

import org.xml.sax.InputSource;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.StaxDriver;

public class XStreamDemo {
   public static void main(String args[]) {
   
      XStreamDemo tester = new XStreamDemo();
      XStream xstream = new XStream(new StaxDriver());
      
      xstream.alias("student", Student.class);
      xstream.alias("note", Note.class);
      
      xstream.useAttributeFor(Student.class, "studentName");
      xstream.aliasField("name", Student.class, "studentName");
      xstream.addImplicitCollection(Student.class, "notes");
      
      Student student = tester.getStudentDetails();
      
      //Object to XML Conversion
      String xml = xstream.toXML(student);
      System.out.println(formatXml(xml));		
   }	

   private Student getStudentDetails() {
      Student student = new Student("Mahesh");
      
      student.addNote(new Note("first","My first assignment."));
      student.addNote(new Note("second","My Second assignment."));
      
      return student;
   }

   public static String formatXml(String xml) {
   
      try {
         Transformer serializer = SAXTransformerFactory.newInstance().newTransformer();
         
         serializer.setOutputProperty(OutputKeys.INDENT, "yes");
         serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
         
         Source xmlSource = new SAXSource(new InputSource(
            new ByteArrayInputStream(xml.getBytes())));
         StreamResult res =  new StreamResult(new ByteArrayOutputStream());            
         
         serializer.transform(xmlSource, res);
         
         return new String(((ByteArrayOutputStream)res.getOutputStream()).toByteArray());
         
      } catch(Exception e) {
         return xml;
      }
   }
}

class Student {
   private String studentName;
   private List<Note> notes = new ArrayList<Note>();
   
   public Student(String name) {
      this.studentName = name;
   }
   
   public void addNote(Note note) {
      notes.add(note);
   }
   
   public String getName() {
      return studentName;
   }
   
   public List<Note> getNotes() {
      return notes;
   }
}

class Note {
   private String title;
   private String description;
   
   public Note(String title, String description) {
      this.title = title;
      this.description = description;
   }
   
   public String getTitle() {
      return title;
   }
   
   public String getDescription() {
      return description;
   }     
}

Output

Verify the output as follows −

<?xml version = "1.0" encoding = "UTF-8"?>
<student name = "Mahesh">
   <note>
      <title>first</title>
      <description>My first assignment.</description>
   </note>
   
   <note>
      <title>second</title>
      <description>My Second assignment.</description>
   </note>
</student>

XStream - Converters

XStream converters are the key components of the XStream library, which are responsible to convert an object to XML and vice versa. XStream provides numerous converters for common types such as primitives, String, File, Collections, arrays, and Dates.

Using Converter

Let us use a SingleValueConvertor whose purpose is to convert an object into a single string. We will use SingleValueConvertor to write an object as attribute string.

Create a Converter

class NameConverter implements SingleValueConverter {

   public Object fromString(String name) {
      String[] nameparts = name.split(",");
      return new Name(nameparts[0], nameparts[1]);
   }
   
   public String toString(Object name) {
      return ((Name)name).getFirstName() + "," + ((Name)name).getLastName();
   }
   
   public boolean canConvert(Class type) {
      return type.equals(Name.class);
   }	
}

Register a Converter

xstream.registerConverter(new NameConverter());

Example - Usage without Converter

Let us first test the code without converter in XStream.

XStreamDemo.java

package com.tutorialspoint.xml;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.stream.StreamResult;

import org.xml.sax.InputSource;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.io.xml.StaxDriver;

public class XStreamDemo {
   public static void main(String args[]) {
   
      XStreamDemo tester = new XStreamDemo();
      XStream xstream = new XStream(new StaxDriver());
      Student student = tester.getStudentDetails();
      xstream.autodetectAnnotations(true);
      
      //Object to XML Conversion
      String xml = xstream.toXML(student);
      System.out.println(formatXml(xml));
   }
   
   private Student getStudentDetails() {
      Student student = new Student("Mahesh","Parashar");
      return student;
   }
   
   public static String formatXml(String xml) {
   
      try {
      
         Transformer serializer = SAXTransformerFactory.newInstance().newTransformer();
         
         serializer.setOutputProperty(OutputKeys.INDENT, "yes");
         serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
         
         Source xmlSource = new SAXSource(new InputSource(
            new ByteArrayInputStream(xml.getBytes())));
         StreamResult res =  new StreamResult(new ByteArrayOutputStream());
         
         serializer.transform(xmlSource, res);
         
         return new String(((ByteArrayOutputStream)res.getOutputStream()).toByteArray());
         
      } catch(Exception e) {
         return xml;
      }
   }
}

@XStreamAlias("student")
class Student {

   @XStreamAlias("name")
   @XStreamAsAttribute
   private Name studentName;

   public Student(String firstName, String lastName) {
      this.studentName = new Name(firstName, lastName);
   }

   public Name getName() {
      return studentName;
   }	
}

class Name {
   private String firstName;
   private String lastName;

   public Name(String firstName, String lastName) {
      this.firstName = firstName;
      this.lastName = lastName;
   }

   public String getFirstName() {
      return firstName;
   }

   public String getLastName() {
      return lastName;
   }     
}

Output

Verify the output as follows −

<?xml version = "1.0" encoding = "UTF-8"?>
<student>
   <name>
      <firstName>Mahesh</firstName>
      <lastName>Parashar</lastName>
   </name>
</student>

Example - Usage with Converter

Let us now test the code with converter in XStream.

XStreamDemo.java

package com.tutorialspoint.xml;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.stream.StreamResult;

import org.xml.sax.InputSource;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.converters.SingleValueConverter;
import com.thoughtworks.xstream.io.xml.StaxDriver;

public class XStreamDemo {

   public static void main(String args[]) {
   
      XStreamDemo tester = new XStreamDemo();
      XStream xstream = new XStream(new StaxDriver());
      Student student = tester.getStudentDetails();		
      
      xstream.autodetectAnnotations(true);
      xstream.registerConverter(new NameConverter());
      
      //Object to XML Conversion
      String xml = xstream.toXML(student);
      System.out.println(formatXml(xml));		
   }	

   private Student getStudentDetails() {
      Student student = new Student("Mahesh","Parashar");		
      return student;
   }

   public static String formatXml(String xml) {

      try {
      
         Transformer serializer = SAXTransformerFactory.newInstance().newTransformer();
         
         serializer.setOutputProperty(OutputKeys.INDENT, "yes");         
         serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
         
         Source xmlSource = new SAXSource(new InputSource(
            new ByteArrayInputStream(xml.getBytes())));
         StreamResult res = new StreamResult(new ByteArrayOutputStream());            
         
         serializer.transform(xmlSource, res);
         
         return new String(((ByteArrayOutputStream)res.getOutputStream()).toByteArray());
         
      } catch(Exception e) {   
         return xml;
      }
   }
}

@XStreamAlias("student")
class Student {

   @XStreamAlias("name")
   @XStreamAsAttribute	
   private Name studentName;

   public Student(String firstName, String lastName) {
      this.studentName = new Name(firstName, lastName);
   }

   public Name getName() {
      return studentName;
   }	
}

class Name {
   private String firstName;
   private String lastName;

   public Name(String firstName, String lastName) {
      this.firstName = firstName;
      this.lastName = lastName;
   }

   public String getFirstName() {
      return firstName;
   }

   public String getLastName() {
      return lastName;
   }     
}

class NameConverter implements SingleValueConverter  {

   public Object fromString(String name) {
      String[] nameparts = name.split(",");
      return new Name(nameparts[0], nameparts[1]);
   }

   public String toString(Object name) {
      return ((Name)name).getFirstName() + "," + ((Name)name).getLastName();
   }

   public boolean canConvert(Class type) {
      return type.equals(Name.class);
   }
}

Output

Verify the output as follows −

<?xml version = "1.0" encoding = "UTF-8"?>
<student name = "Mahesh,Parashar"/>

XStream - Custom Converter

XStream allows writing a converter from scratch, so that the developer can write a completely new implementation on how to serialize an object to XML and vice versa. A converter interface provides three methods −

  • canConvert − It is a check for supported object type serialization.

  • marshal − It serializes an object to XML.

  • unmarshal − It de-serializes an object from XML.

Step 1: Implement Converter Interface

class StudentConverter implements Converter {

   public boolean canConvert(Class object) {
      return object.equals(Student.class);
   }
   
   public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) {
      Student student = (Student) value;
      writer.startNode("name");
      writer.setValue(student.getName().getFirstName() + "," + student.getName().getLastName());
      writer.endNode();
   }
   
   public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
      reader.moveDown();
      String[] nameparts = reader.getValue().split(",");
      Student student = new Student(nameparts[0],nameparts[1]);
      reader.moveUp();
      return student;
   }
}	

Step 2: Register Converter

xstream.registerConverter(new StudentConverter());

Example - Usage of Custom Converter

Let us now test the code with custom converter in XStream.

XStreamTester.java

package com.tutorialspoint.xml;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.stream.StreamResult;

import org.xml.sax.InputSource;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.StaxDriver;

public class XStreamDemo {

   public static void main(String args[]) {
      XStreamDemo tester = new XStreamDemo();
      XStream xstream = new XStream(new StaxDriver());
      Student student = tester.getStudentDetails();		
      xstream.autodetectAnnotations(true);
      xstream.registerConverter(new StudentConverter());
      
      //Object to XML Conversion
      String xml = xstream.toXML(student);
      System.out.println(formatXml(xml));		
   }	

   private Student getStudentDetails() {
      Student student = new Student("Mahesh","Parashar");		
      return student;
   }

   public static String formatXml(String xml) {
      try {
         Transformer serializer = SAXTransformerFactory.newInstance().newTransformer();
         serializer.setOutputProperty(OutputKeys.INDENT, "yes");
         serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
         Source xmlSource = new SAXSource(new InputSource(
            new ByteArrayInputStream(xml.getBytes())));
         StreamResult res =  new StreamResult(new ByteArrayOutputStream());            
         serializer.transform(xmlSource, res);
         return new String(((ByteArrayOutputStream)res.getOutputStream()).toByteArray());
      } catch(Exception e) {
         return xml;
      }
   }   
}

@XStreamAlias("student")
class Student {

   @XStreamAlias("name")
   private Name studentName;

   public Student(String firstName, String lastName) {
      this.studentName = new Name(firstName, lastName);
   }

   public Name getName() {
      return studentName;
   }	
}

class Name {
   private String firstName;
   private String lastName;

   public Name(String firstName, String lastName) {
      this.firstName = firstName;
      this.lastName = lastName;
   }

   public String getFirstName() {
      return firstName;
   }

   public String getLastName() {
      return lastName;
   }     
}

class StudentConverter implements Converter {

   public void marshal(Object value, HierarchicalStreamWriter writer,
      MarshallingContext context) {
      Student student = (Student) value;
      writer.startNode("name");
      writer.setValue(student.getName().getFirstName() + "," + student.getName().getLastName());
      writer.endNode();
   }

   public Object unmarshal(HierarchicalStreamReader reader,
      UnmarshallingContext context) {
      reader.moveDown();
      String[] nameparts = reader.getValue().split(",");
      Student student = new Student(nameparts[0],nameparts[1]);
      reader.moveUp();
      return student;
   }

   public boolean canConvert(Class object) {
      return object.equals(Student.class);
   }
}	

Output

Verify the output as follows −

<?xml version = "1.0" encoding = "UTF-8"?>
<student>
   <name>Mahesh,Parashar</name>
</student>
Advertisements