解决fastjson中"$ref重复引用"的问题,先来看一个例子吧:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
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默认开启引用检测将相同的对象写成引用的形式:
1
2
3
4
5
|
{ "$ref" : "$" } // 引用根对象
{ "$ref" : "@" } // 引用自己
{ "$ref" : ".." } // 引用父对象
{ "$ref" : "../.." } // 引用父对象的父对象
{ "$ref" : "$.members[0].reportto" } // 基于路径的引用
|
目前来说,前端还没有一个很好的办法来解析这样的json格式。
除了上面的重复引用外, 还衍生出了另外一个概念:"循环引用",下面来看下两者之间的区别吧:
- 重复引用:指一个对象引用重复出现多次
- 循环引用:对象a引用对象b,对象b引用对象a(这种情况一般是个雷区,轻易不要尝试的好,很容易引发*error)
再来看一个循环引用的例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
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引用检测机制(慎用,循环引用时可能导致*error)
1
|
json.tojsonstring(obj, serializerfeature.disablecircularreferencedetect)
|
避免循环引用(某一方的引用字段不参与序列化:@jsonfield(serialize=false))
避免一个对象引用被重复使用多次(使用拷贝的对象副本来完成json数据填充)
1
2
3
4
5
6
7
8
9
10
11
|
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));
}
|
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://segmentfault.com/a/1190000017197731