栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

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

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

解决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 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]"}]}


上面的现象就是将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));
}

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/139582.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号