Fastjson JSONObject.toJSONString 出现 $ref: "$."的解决办法(重复引用)

首先,fastjson作为一款序列化引擎,不可避免的会遇到循环引用的问题,为了避免StackOverflowError异常,fastjson会对引用进行检测。
如果检测到存在重复/循环引用的情况,fastjson默认会以“引用标识”代替同一对象,而非继续循环解析导致StackOverflowError。

  1. 解决办法1
 关闭检查:
JSON.toJSONString(object, SerializerFeature.DisableCircularReferenceDetect);

  2. 解决办法2:
创建新对象 不循环引用

问题根本原因找到了。是因为我下面那段代码的时候,重复给map赋值了相同key的值,只是改变了值的内容。
实际上,Map.get()出来的内容是持有map里的对象引用的,所以修改了对象的值之后,Map里的值自动改好了,不需要再进行Map.put();
如果再做一次Map.put();相当于对同一个key插入了之前这个key的同一个引用。就会触发FastJson的循环引用保护机制。导致出现$ref: "$."

当然,用

JSON.toJSONString(object, SerializerFeature.DisableCircularReferenceDetect);


这个方法可以解决掉出现 $ref: “$.”的问题。但实际上,那个循环引用会导致别的key里面的内容被挤掉。最后数据还是错误的。

解决方案

所以根本解决办法是:

不要对Map进行相同key的赋值操作。如果要修改这个key对应的value,如果value是对象,需要先get,再对对象引用进行修改,这样Map会自动修改。
        //这里添加导致重复添加,map序列错乱,Fastjson编译出来的内容有问题;
        typeList.put(mImageNameTypeId, typeItem);

        Log.d(TAG + " maomao onDelete 删除照片前 fastjson typeList:" + JSON.toJSONString(typeList));
        TypeItem typeItem = typeList.get(typeId);
        String imgNameStr = typeItem == null ? "" : typeItem.TypeValue;
        String[] imgNames = imgNameStr.split(",");
        imgNames[position] = "";
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < imgNames.length; i++) {
            if (!TextUtils.isEmpty(imgNames[i])) {
                sb.append(imgNames[i]).append(",");
            }
        }
        Log.d(TAG + " onDelete 删除照片 before imgNames:" + imgNameStr);
        Log.d(TAG + " onDelete 删除照片 after imgNames:" + sb.toString());
        if (sb.lastIndexOf(",") >= 0 && sb.lastIndexOf(",") == sb.length() - 1) {
            String substring = sb.substring(0, sb.length() - 1);
            sb.replace(0, sb.length(), substring);
        }
        Log.d(TAG + " onDelete 删除照片 after sub string imgNames:" + sb.toString());
        typeItem.TypeValue = sb.toString();
        //typeList.put(mImageNameTypeId, typeItem);//这里添加导致重复添加,map序列错乱,Fastjson编译出来的内容有问题;
        Log.d(TAG + " maomao onDelete 删除照片后 fastjson typeList:" + JSON.toJSONString(typeList));