Short and Sweet Serialization Code
As you can see in the code snippet immediately below and in the source code accompanying this article, it only requires three lines of code to serialize or de-serialize an object or XML document. Of course, your XML should be well formed and this is especially critical because, as mentioned previously, XStream does not provide any validation. I've copied the snippet below from the XStream web site and you'll notice the caveat about the XPP3 library. This library is a high-performance XML parsing library but I found the DOM parser implementation adequate for my needs. Your mileage may vary.
//Convert a Java object to XML
XStream xstream = new XStream();
XStream xstream = new XStream(new DomDriver()); // does not require XPP3 library
String xml = xstream.toXML(joe);
//Convert XML to a Java object using the
//same xstream reference
Person joe = xstream.fromXML(joeXML); //joeXML not shown
I've encountered one limitation using XStream and this too is duly noted on the project web site: If you're using a JDK prior to 1.4x you must provide a no-arg default constructor in order to deserialize objects and instantiate them correctly. While I did have to add this plumbing to some existing classes, it wasn't a big obstacle to overcome.
Among the many impressive aspects of XStream's implementation are that ease of use and clean XML are obviously highly valued by its authors. When serializing to XML you can alias the fully qualified class name to make the output more readable. As you can see in the snippet below, only one line of code is required to achieve this:
//class name: com.tillman.transport.sport.SportUtilityVehicle
With the above line of code the output XML will begin with the element <suv> rather than the default <com.tillman.transport.sport.SportUtilityVehicle> that the class converter would normally produce.
Understanding XStream's Design
You'll observe in the sample code accompanying the article that XStream is capable of serializing a nested object graph and I have had occasion to test this down several levels of depth. Moreover, as mentioned previously, XStream builds its XML using a robust set of converter classes that handle many of the standard Java types that you will encounter, including a fair number of the Collections classes. The XStream reference page describing the converters sums up their role as follows:
The core of XStream consists of a registry of 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.
Because the converters are the core of XStream I recommend that you peruse the XStream Converters reference before you start your project. If you have a picture of how the XML will look for a given type or collection it will make your output easier to understand.
Table 1 is an example from the Converters reference. It shows the XML generated using the default Map Converter in the right column and the three classes, any of which will generate that output, in the left column.
Table 1. The Java classes in the left column generate the XML at right when using XStream's Map Converter.
Also, there is one other fairly obvious shortcut that I'd like to share that saved me some effort. Rather than trying to figure out the XML first, incrementally massaging it into the correct format, let XStream do the heavy lifting. Code your class and write a test harness to generate the serialized XML. Using XStream in "both directions" in your system is the optimal way to ensure that your objects and XML seamlessly convert back and forth. However, in a heterogeneous or a distributed system where you don't control both ends of the pipe, this obviously isn't always possible.
So, when should you use Java-XML binding and when is Java-XML serialization more appropriate? If you have some concern about the correctness of your XML input then ensuring your data will produce a valid object only makes sense. If you have control of the build process and generating source code is an option then Java-XML binding will allow you to create your objects such that they can be created and validated against a schema or DTD. On the other hand, if you can perform the serialization and deserialization of your objects using XStream, then this powerful library will definitely save you a lot of time and effort and greatly reduce the complexity of your XML processing.