本文写于 12 年前(2013 年 12 月),部分内容可能已经过时。

假如一个对象里面引用了自己,那么序列化的时候如果不做特殊处理就会死循环了。在XStream中是采用reference处理的。反序列化的时候也根据reference来特殊处理。JSON也是类似的,不过貌似支持不是很好。

package me.arganzheng.study.xstream;

import org.apache.commons.lang.StringUtils;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver;

/**
 * 循环引用序列化例子
 * 
 * @author arganzheng
 * @date 2013-12-27
 */
class Person {

    String firstname = "argan";
    String lastname  = "zheng";

    Person me      = this;

    @Override
    public String toString() {
        return "Person [firstname=" + firstname + ", lastname=" + lastname + "]";
    }
}

public class XStreamTest {

    public static void main(String[] args) {

        XStream xs = new XStream();
        xs.alias(StringUtils.uncapitalize(Person.class.getSimpleName()), Person.class);

        Person person = new Person();
        person.me = new Person();

        String xml = xs.toXML(person);
        System.out.println(xml);

        Person p = (Person) xs.fromXML(xml);
        System.out.println(p);

        XStream jsonXStream = new XStream(new JettisonMappedXmlDriver());
        //jsonXStream.setMode(XStream.NO_REFERENCES);
        String json = jsonXStream.toXML(person);
        System.out.println(json);
    }
}

输入结果:

<person>
  <firstname>argan</firstname>
  <lastname>zheng</lastname>
  <me>
    <firstname>argan</firstname>
    <lastname>zheng</lastname>
    <me reference=".."/>
  </me>
</person>
Person [firstname=argan, lastname=zheng]
{"com.qq.b2b2c.api.container.controller.Person":{"firstname":"argan","lastname":"zheng","me":[{"firstname":"argan","lastname":"zheng"},{"@reference":".."}]}}

本文由 arganzheng 创作,采用 CC BY 4.0 许可协议。在保留原文作者、署名以及完整原文链接(https://arganzheng.life/circular-reference-serialization-problem.html)的前提下,欢迎各种形式的转载、翻译或商业引用。


COMMENTS

评论存放在 GitHub Discussions, 用 GitHub 账号登录即可发表,支持 Markdown。 想针对正文某句话说?选中那段文字,点浮出的「评论」即可划线评论;觉得哪里写错了,发表时勾上「同时提交 Issue」。 有人回复你时 GitHub 会按你的通知设置发邮件,不用守在这里。

×