好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

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

解决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(这种情况一般是个雷区,轻易不要尝试的好,很容易引发stackoverflowerror)

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

?

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引用检测机制(慎用,循环引用时可能导致stackoverflowerror)

?

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测试数据/a/1190000017197731

查看更多关于解决FastJson中"$ref重复引用"的问题方法的详细内容...

  阅读:21次