I usually post about Dev stuff on Twitter - you can follow me there:
Follow @baeldung1. Overview
This is the third article in a series about XStream. If you want to learn about its basic use in converting Java objects to XML and vice versa, please refer to the previous articles.
Beyond its XML-handling capabilities, XStream can also convert Java objects to and from JSON. In this tutorial, we will learn about these features.
2. Prerequisites
Before reading this tutorial, please go through the first article in this series, in which we explain the basics of the library.
3. Dependencies
<dependency> <groupId>com.thoughtworks.xstream</groupId> <artifactId>xstream</artifactId> <version>1.4.5</version> </dependency>
4. JSON Drivers
In the previous articles, we learned how to set up an XStream instance and to select an XML driver. Similarly, there are two drivers available to convert objects to and from JSON: JsonHierarchicalStreamDriver and JettisonMappedXmlDriver.
4.1. JsonHierarchicalStreamDriver
This driver class can serialize objects to JSON, but is not capable of deserializing back to objects. It does not require any extra dependencies, and its driver class is self-contained.
4.2. JettisonMappedXmlDriver
This driver class is capable of converting JSON to and from objects. Using this driver class, we need to add an extra dependency for jettison.
<dependency> <groupId>org.codehaus.jettison</groupId> <artifactId>jettison</artifactId> <version>1.3.7</version> </dependency>
5. Serializing an Object to JSON
Let’s create a Customer class:
public class Customer { private String firstName; private String lastName; private Date dob; private String age; private List<ContactDetails> contactDetailsList; // getters and setters }
Note that we have (perhaps unexpectedly) created age as a String. We will explain this choice later.
5.1. Using JsonHierarchicalStreamDriver
We will pass a JsonHierarchicalStreamDriver to create an XStream instance.
xstream = new XStream(new JsonHierarchicalStreamDriver()); dataJson = xstream.toXML(customer);
This generates the following JSON:
{ "com.baeldung.pojo.Customer": { "firstName": "John", "lastName": "Doe", "dob": "1986-02-14 16:22:18.186 UTC", "age": "30", "contactDetailsList": [ { "mobile": "6673543265", "landline": "0124-2460311" }, { "mobile": "4676543565", "landline": "0120-223312" } ] } }
5.2. JettisonMappedXmlDriver Implementation
We will pass a JettisonMappedXmlDriver class to create an instance.
xstream = new XStream(new JettisonMappedXmlDriver()); dataJson = xstream.toXML(customer);
This generates the following JSON:
{ "com.baeldung.pojo.Customer": { "firstName": "John", "lastName": "Doe", "dob": "1986-02-14 16:25:50.745 UTC", "age": 30, "contactDetailsList": [ { "com.baeldung.pojo.ContactDetails": [ { "mobile": 6673543265, "landline": "0124-2460311" }, { "mobile": 4676543565, "landline": "0120-223312" } ] } ] } }
5.3. Analysis
Based on the output from the two drivers, we can clearly see that there are some slight differences in the generated JSON. For example, JettisonMappedXmlDriver omits the double quotes for numeric values despite the data type being java.lang.String:
"mobile": 4676543565, "age": 30,
JsonHierarchicalStreamDriver, on the other hand, retains the double quotes.
6. Deserializing JSON to an Object
Let’s take the following JSON to convert it back to a Customer object:
{ "customer": { "firstName": "John", "lastName": "Doe", "dob": "1986-02-14 16:41:01.987 UTC", "age": 30, "contactDetailsList": [ { "com.baeldung.pojo.ContactDetails": [ { "mobile": 6673543265, "landline": "0124-2460311" }, { "mobile": 4676543565, "landline": "0120-223312" } ] } ] } }
Recall that only one of the drivers (JettisonMappedXMLDriver) can deserialize JSON. Attempting to use JsonHierarchicalStreamDriver for this purpose will result in an UnsupportedOperationException.
Using the Jettison driver, we can deserialize the Customer object:
customer = (Customer) xstream.fromXML(dataJson);
7. Conclusion
In this article we have covered the JSON handling capabilities XStream, converting objects to and from JSON. We also looked at how we can tweak our JSON output, making it shorter, simpler and more readable.
As with XStream’s XML processing, there are other ways we can further customize the way JSON is serialized by configuring the instance, using either annotations or programmatic configuration. For more details and examples, please refer to the first article in this series.
The complete source code with examples can be downloaded from the linked GitHub repository.