Java XStream – Complex Example

Today we will tell you more about java XStream. If you are looking for basics of java XStream please refer to our earlier tutorial – Java Xstream.
Here is our more advanced code snippet.

ComplexExample.java

package com.itcuties.java.xstream.data;

import java.io.ObjectStreamException;
import java.util.List;

import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.annotations.XStreamImplicit;

/**
* More complex example. It is a summary of already showed issues. It also shows
* several additional things: <li>transient field modifier will cause the field
* NOT to be loaded even if annotated and present in xml <li>constructor is not
* being invoked <li>default values given to fields will be replaced if the
* fields are present in xml file <li>how to force xstream to set a default
* value for an attribute if it is not present in xml
*
* @author itcuties
*
*/
@XStreamAlias("complex-example")
public class ComplexExample {
   @XStreamAlias("number-1")
   private int number1 = 9;// default value will be replaced if present in the xml

   @XStreamAlias("number-2")
   private int number2 = 12;// default value will be erased if NOT present in xml (in this case it will be set to 0)

   @XStreamAlias("number-3")
   private Short number3;// any numeric type will do (Object or primitive) just make sure the number value will fit

   @XStreamAlias("attribute")
   @XStreamAsAttribute
   private String attribute;

   @XStreamAlias("default-attribute")
   @XStreamAsAttribute
   private String defaultAttribute;

   @XStreamAlias("transientString")
   private transient String transientString;// this will not be read because it
                                               // is transient

   @XStreamImplicit(itemFieldName = "data")
   private List<String> data;

   @XStreamAlias("book")
   private Book book; // you can use other classes that were annotated
                       // (just give the top most class to xstream for
                       // annotation processing,
                       // it will find all others that are used)

   public ComplexExample() {
       System.out.println("Very talkative constructor.");
   }

   @Override
   public String toString() {
       return "ComplexExample [number1=" + number1 + ", number2=" + number2
               + ", number3=" + number3 + ", attribute=" + attribute
               + ", defaultAttribute=" + defaultAttribute
               + ", transientString=" + transientString + ", data=" + data
               + ", book=" + book + "]";
   }

   /**
    * There is one major flaw in XStream. Unfortunately it has no way of
    * telling if a field or attribute should get any default value if not
    * present in the xml file. Because constructor is not being invoked we
    * cannot set the value there. Neither setting the value in field definition
    * will work. The resulting instance will always have zero or null values in
    * the fields.
    *
    * The only way of setting the desired default value is using the following
    * method. It is called during deserialization process and here we can check
    * if the field value is null. If yes it means that it's tag is not present
    * and we can set the default value if needed.
    *
    * @return this
    * @throws ObjectStreamException
    */
   private/* or public or protected or none */Object readResolve()
           throws ObjectStreamException {
       if (defaultAttribute == null) {
           defaultAttribute = "DEFAULT ATTRIBUTE VALUE";
       }
       return this;
   }
}

complex-example.xml

<complex-example attribute="some attribute">
   <number-1>1</number-1>
   <number-3>3</number-3>
   <transientString>
       Some transient string that will not be loaded.
   </transientString>

   <data>A</data>
   <data>B</data>
   <data>C</data>
   <data>D</data>
   <data>E</data>

   <book>
       <title>The Lord of The Rings</title>
       <author>J.R.R. Tolkien</author>
       <pages-count>1024</pages-count>
   </book>
</complex-example>

To read java object from xml call the fromXML method of the XStream class. Here is the example.

XStream xStream = new XStream();
xStream.processAnnotations(ComplexExample.class);
Object readObject = xStream.fromXML(new File("xmls/complex-example.xml"));
System.out.println("Object loaded by xstream: " + readObject);

When you will run this example you’ll get the following output.

Object loaded by xstream: ComplexExample [number1=1, number2=0, number3=3, attribute=some attribute, defaultAttribute=DEFAULT ATTRIBUTE VALUE, transientString=null, data=[A, B, C, D, E], book=Book [title=The Lord of The Rings, author=J.R.R. Tolkien, pagesCount=1024, fieldThatIsNotInTheXml=null]]

Code summary

There are some things to remember here and they are as follow…

transient keyword

When you use a transient keyword for a class attribute it’s value will not be read from the XML file although it is present there.

Default constructor

Class default constructor is not called to create the object while reading it from XML file.

Default values

If you want to set class default values which are different from the default java types values ( 0 for int, false for boolean etc.) you need to assign them manually in the readResolve() method.

Using annotated classes

You can use other classes that were annotated, just give the top most class to xstream for annotation processing it will find all others that are used.

Download this sample code here.

This code is available on our GitHub repository as well.

One Response to "Java XStream – Complex Example"

  1. praveen says:

    Hi… You saved me with this brilliant tutorial, Im struggling from one day to solve an issue in a Complex XML as you shown in this example… It really helped to solve the issue. Thank you so much for your valuable tutorial…..

    Reply

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>