Due to XStream's flexible architecture, handling of JSON mappings is as easy as handling of XML documents. All you have to do is to initialize XStream object with an appropriate driver and you are ready to serialize your objects to (and from) JSON.
XStream currently delivers two drivers for JSON: The JsonHierarchicalStreamDriver and the JettisonMappedXmlDriver. The first one does not have an additional dependency, but can only be used to write XML, while the second one is based on Jettison and can also deserialize JSON to Java objects again. However, since the JettisonMappedXmlDriver transforms plain XML into JSON, you might get better JSON strings with the JsonHierarchicalStreamDriver, because this driver knows often about the type of the written data and can act properly.
One word of warning. JSON is made for an easy data transfer between systems and languages. It's syntax offers much less possibilities to express certain data structures. It supports name/value pairs of primitive data types, arrays and lists and allows to nest them - but that's it! No references, no possibility for meta data (attributes), etc. Therefore do not expect wonders. XStream (and Jettison) try their best, but the procedure to convert any kind of object into JSON is a lossy transformation and especially deserialization will not be possible for any construct. See also FAQ
.Jettison driver uses Jettison StAX parser to read and write data in JSON
format. It is available in XStream from version 1.2.2 and is implemented in
com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver
class. To successfully use this driver you need
to have Jettison project and StAX API in your classpath (see reference for
optional dependencies).
Alternatively you can download JARs manually.
Here are a few simple examples:
The following example:
package com.thoughtworks.xstream.json.test; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver; public class WriteTest { public static void main(String[] args) { Product product = new Product("Banana", "123", 23.00); XStream xstream = new XStream(new JettisonMappedXmlDriver()); xstream.alias("product", Product.class); System.out.println(xstream.toXML(product)); } }
produces the following JSON document:
{"product":{"name":"Banana","id":"123","price":"23.0"}}
As you can see, all standard XStream features (such as aliases) can be used with this driver.
The only difference to the example above is the line with the initialization:
XStream xstream = new XStream(new JsonHierarchicalStreamDriver());
The output is as follows:
{"product": { "name": "Banana", "id": "123", "price": 23.0 }}
While the difference because of line feeds is immediately obvious, you have to note also the value of the price element. This time the driver knew about the numeric value and therefore no quotes were generated.
Note that newer Jettison releases than 1.0-RC2 will also try to detect numerical values and omit the quotes. Since Jettison cannot know about the original data type, it has to guess. Hence it will therefore also write the value of the id field as numeric value in future.
The following code:
package com.thoughtworks.xstream.json.test; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver; public class ReadTest { public static void main(String[] args) { String json = "{\"product\":{\"name\":\"Banana\",\"id\":\"123\"" + ",\"price\":\"23.0\"}}"; XStream xstream = new XStream(new JettisonMappedXmlDriver()); xstream.alias("product", Product.class); Product product = (Product)xstream.fromXML(json); System.out.println(product.getName()); } }
serializes JSON document created with preceding example back to Java object. It prints:
Banana
as a result.