XStream 序列化对象到JSON

本文介绍XStream库如何处理JSON映射,包括使用JettisonMappedXmlDriver和JsonHierarchicalStreamDriver进行序列化和反序列化的示例。展示了如何将Java对象转换为JSON字符串,并从JSON读取数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JSON Tutorial

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

.

Since JSON has no possibility to express references, you should always set the NO_REFERENCES mode writing JSON.

Jettison driver

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:

Write to JSON with the Jettison-based implementation

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.setMode(XStream.NO_REFERENCES);
        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.

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.

Write to JSON with the self-contained JSON 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.

Write to JSON with the self-contained JSON driver dropping the root

Sometimes the root node in the generated JSON is superfluous, since its name is caused by the Java type of the written object that has no meaning in JSON and increases only the nesting level of the structure. Therefore it is possible to drop this root by initializing the internally used JsonWriter in a different mode. Again, the only difference to the example above is the line with the initialization:

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

The output is as follows:

{
  "name": "Banana",
  "id": "123",
  "price": 23.0
}

Note, that it is now possible to create invalid JSON if XStream should marshal a single object with a single value to JSON (like String, int, URL, ...). JSON requires that the root is actually an object, but by dropping the root all that is generated is a single value. You can force the JsonWriter to throw a ConversionException in this case, see Javadoc of the JsonWriter.

Read from JSON

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.

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值