日期:2014-05-16  浏览次数:20447 次

fastjson-循环引用
很多用户在初次使用fastjson时都遇到了循环引用的问题,这是反映最多的问题,我越来越认识到支持循环引用的必要性。经过测试,加入循环应用的支持对性能的影响很小,小于5%。我决定在1.1.3加入循环应用支持,而且是缺省打开这个特性。

fastjson支持的循环应用是自然的,不需要象jackson那样,需要Annotation设置。fastjson支持的引用,是基于path的,方便javascript解析。

语法
{"$ref":"$"} // 引用根对象
{"$ref":"$"} // 引用根对象
{"$ref":"@"} // 引用自己
{"$ref":".."} // 引用父对象
{"$ref":"../.."} // 引用父对象的父对象
{"$ref":"$.members[0].reportTo"} // 基于路径的引用
测试代码
public void test_ref() throws Exception {
    Group admin = new Group("admin");

    User jobs = new User("jobs");
    User sager = new User("sager");
    User sdh5724 = new User("sdh5724");

    admin.getMembers().add(jobs);
    jobs.getGroups().add(admin);

    admin.getMembers().add(sager);
    sager.getGroups().add(admin);

    admin.getMembers().add(sdh5724);
    sdh5724.getGroups().add(admin);
    
    sager.setReportTo(sdh5724);
    jobs.setReportTo(sdh5724);

    SerializeConfig serializeConfig = new SerializeConfig();
    serializeConfig.setAsmEnable(false);
    String text = JSON.toJSONString(admin, serializeConfig, SerializerFeature.PrettyFormat);
    System.out.println(text);
    
    ParserConfig config = new ParserConfig();
    config.setAsmEnable(false);
    
    JSON.parseObject(text, Group.class, config, 0);
}

public static class Group {
    private String     name;
    private List<User> members = new ArrayList<User>();
    public Group(){
    }
    public Group(String name){
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public List<User> getMembers() {
        return members;
    }
    public void setMembers(List<User> members) {
        this.members = members;
    }
    public String toString() {
        return this.name;
    }
}
public static class User {
    private String      name;
    private List<Group> groups = new ArrayList<Group>();
    private User        reportTo;
    public User(){
    }
    public User getReportTo() {
        return reportTo;
    }
    public void setReportTo(User reportTo) {
        this.reportTo = reportTo;
    }
    public User(String name){
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
      &