0
点赞
收藏
分享

微信扫一扫

FastJson出现{"$ref":"$[0]"}解决方案

1. 案例代码

1.1 案例一

多个元素持有同一个引用时。

案例代码:

public class TestFastJson {
    public static void main(String[] args) {
        ceshi();
    }

    public static void ceshi(){
        List<User> list = new ArrayList<>();
        //注意:此处的对象为同一个
        User user = new User();
        for (int i = 0; i <3 ; i++) {
            user.setName("李白");
            user.setAge("20");
            list.add(user);
        }

        String string = JSON.toJSONString(list);
        System.out.println(string);
    }

    @Data
    public static class User {
        private String name;
        private String age;
    }

}

响应结果:

[{"age":"20","name":"李白"},{"$ref":"$[0]"},{"$ref":"$[0]"}]

1.2 案例二

多个元素内部持有同一个引用时。

public class TestFastJson {


    public static void main(String[] args) {
        test2();
    }

    public static void test2() {
        List<UserPo> userPos = new ArrayList<>();

        //注意:此处的引用是一个
        List<Order> o1s = new ArrayList<>();
        Order o1 = new Order();
        o1.setId(100L);
        o1.setOrderName("水瓶");
        o1s.add(o1);


        UserPo u1 = new UserPo();
        u1.setId(1L);
        u1.setAge(12);
        u1.setUserName("tom");
        u1.setPassword("1");
        //持有的是同一个order引用
        u1.setOrders(o1s);


        UserPo u2 = new UserPo();
        u2.setId(2L);
        u2.setAge(12);
        u2.setUserName("tom");
        u2.setPassword("2");
        //持有的是同一个order引用
        u2.setOrders(o1s);

        userPos.add(u1);
        userPos.add(u2);
        System.out.println(JSON.toJSONString(userPos));
    }

    @Data
    public static class UserPo {
        private Long id;

        private String userName;

        private String password;

        private Integer age;

        private List<Order> orders;
    }

}

响应报文:

[{"age":12,"id":1,"orders":[{"id":100,"orderName":"水瓶","price":0.0}],"password":"1","userName":"tom"},{"age":12,"id":2,"orders":[{"$ref":"$[0].orders[0]"}],"password":"2","userName":"tom"}]

2. 解决方案

方案一:通过对象拷贝的方式,使得同一个对象的属性值复制到不同的对象中。

方案二:关闭FastJson的循环引用的检查:

JSON.toJSONString(userPos, SerializerFeature.DisableCircularReferenceDetect)

3. 项目中实际遇到的场景

在实际项目中,我们一般会避免案例代码中的书写方式。

但是还是可能会遇到{"$ref":"$[0]"}

  1. 查询某接口,得到详细数据(无序且存在重复的元素(重复的元素不是同一个引用))。
  2. 需要对详细数据排序:
    2.1 将详细数据转换成Map(注意:此时重复的元素只会保留一个)。
    2.2 遍历有序的数据,将详细数据排序(此处会造成多个元素持有一个map中的value引用)。
  3. 使用FastJson对2的返回结果格式化。

此时,JSON格式化数据的解决方案就是在序列化对象的同时,使用SerializerFeature.DisableCircularReferenceDetect(关闭引用检查)。

举报

相关推荐

0 条评论