当前位置: 移动技术网 > IT编程>开发语言>Java > 解决FastJson中"$ref重复引用"的问题方法

解决FastJson中"$ref重复引用"的问题方法

2019年07月19日  | 移动技术网IT编程  | 我要评论

解决fastjson中"$ref重复引用"的问题,先来看一个例子吧:

public static void main(string[] args) {
 usergroup usergroup = new usergroup().setname("usergroup");

 user user = new user("user");
 for (int i = 0; i < 3; i++) {
  usergroup.adduser(user);
 }
 console.log(json.tojsonstring(usergroup));
}


@data
@allargsconstructor
static class user {
 private string name;
}

@data
@accessors(chain = true)
static class usergroup {
 private string name;
 private list<user> users = lists.newarraylist();

 public usergroup adduser(user user) {
  this.getusers().add(user);
  return this;
 }
}

输出结果:

{"name":"usergroup","users":[{"name":"user"},{"$ref":"$.users[0]"},{"$ref":"$.users[0]"}]}

<!--- more --->

上面的现象就是将user对象的引用重复使用造成了重复引用问题,fastjson默认开启引用检测将相同的对象写成引用的形式:

{"$ref": "$"} // 引用根对象
{"$ref":"@"} // 引用自己
{"$ref":".."} // 引用父对象
{"$ref":"../.."} // 引用父对象的父对象
{"$ref":"$.members[0].reportto"} // 基于路径的引用

目前来说,前端还没有一个很好的办法来解析这样的json格式。

除了上面的重复引用外, 还衍生出了另外一个概念:"循环引用",下面来看下两者之间的区别吧:

  • 重复引用:指一个对象引用重复出现多次
  • 循环引用:对象a引用对象b,对象b引用对象a(这种情况一般是个雷区,轻易不要尝试的好,很容易引发stackoverflowerror)

再来看一个循环引用的例子:

public static void main(string[] args) {
 order order = new order().setname("order");
 item item = new item().setname("item");

 item.setorder(order);
 order.setitem(item);

 console.log(json.tojsonstring(order));
 console.log("----------------------------");
 console.log(json.tojsonstring(item));
}

@data
@accessors(chain = true)
static class order {
 private string name;
 private item item;
}

@data
@accessors(chain = true)
static class item {
 private string name;
 private order order;
}

{"item":{"name":"item","order":{"$ref":".."}},"name":"order"}
----------------------------
{"name":"item","order":{"item":{"$ref":".."},"name":"order"}}

解决方案

关闭fastjson引用检测机制(慎用,循环引用时可能导致stackoverflowerror)

json.tojsonstring(obj, serializerfeature.disablecircularreferencedetect)

避免循环引用(某一方的引用字段不参与序列化:@jsonfield(serialize=false))

避免一个对象引用被重复使用多次(使用拷贝的对象副本来完成json数据填充)

public static void main(string[] args) {
 usergroup usergroup = new usergroup().setname("usergroup");

 user user = new user("user");
 for (int i = 0; i < 3; i++) {
  user duplicateuser = new user();
  beanutil.copyproperties(user, duplicateuser);
  usergroup.adduser(duplicateuser);
 }
 console.log(json.tojsonstring(usergroup));
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网