问题描述

springmvc中使用fastjson,在前台发现了"$ref": "$.apis.我的[1].methods[2].bodyobject.jsondocTemplate"这一种引用.

解决方案

通过设置DisableCircularReferenceDetect来禁用循环引用:

  1. 前端js单独处理
    var FastJson = {
     isArray: function(a) {
         return "object" == typeof a && "[object array]" == Object.prototype.toString.call(a).toLowerCase();
     },
     isObject: function(a) {
         return "object" == typeof a && "[object object]" == Object.prototype.toString.call(a).toLowerCase();
     },
     format: function(a) {
         if (null == a) return null;
         "string" == typeof a && (a = eval("(" + a + ")"));
         return this._format(a, a, null, null, null);
     },
     _randomId: function() {
         return "randomId_" + parseInt(1E9 * Math.random());
     },
     _getJsonValue: function(a, c) {
         var d = this._randomId(),
         b;
         b = "" + ("function " + d + "(root){") + ("return root." + c + ";");
         b += "}";
         b += "";
         var e = document.createElement("script");
         e.id = d;
         e.text = b;
         document.body.appendChild(e);
         d = window[d](a);
         e.parentNode.removeChild(e);
         return d;
     },
     _format: function(a, c, d, b, e) {
         d || (d = "");
         if (this.isObject(c)) {
             if (c.$ref) {
                 var g = c.$ref;
                 0 == g.indexOf("$.") && (b[e] = this._getJsonValue(a, g.substring(2)));
                 return
             }
             for (var f in c) b = d,
             "" != b && (b += "."),
             g = c[f],
             b += f,
             this._format(a, g, b, c, f);
         } else if (this.isArray(c)) for (f in c) b = d,
         g = c[f],
         b = b + "[" + f + "]",
         this._format(a, g, b, c, f);
         return a;
     }
    };
    
  2. 后台序列化前设置禁用循环引用 重点在SerializerFeature feature = SerializerFeature.DisableCircularReferenceDetect;这句.
    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.serializer.SerializerFeature;
    public class Test {
     public static void main(String[] args) {
         Map<String, Student> maps = new HashMap<String, Student>();
         Student s1 = new Student("s1", 16);
         maps.put("s1", s1);
         maps.put("s2", s1);
         SerializerFeature feature = SerializerFeature.DisableCircularReferenceDetect;
         byte[] bytes = JSON.toJSONBytes(maps, feature);
         System.out.println(new String(bytes));
     }
    }
    
  3. 字段名称上配置
    // 字段名上添加
    @JSONField(serialize = false)
    
  4. spring mvc中配置转换禁用循环引用
     <bean id="fastJsonHttpMessageConverter" class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
         <property name="supportedMediaTypes">
             <list>
                 <value>application/json;charset=UTF-8</value>
                 <value>text/html;charset=UTF-8</value>
             </list>
         </property>
         <property name="features">
             <list>
                 <value>QuoteFieldNames</value>
                 <value>WriteDateUseDateFormat</value>
                 <!-- 禁用循环检测 -->
                 <value>DisableCircularReferenceDetect</value>
             </list>
         </property>
     </bean>
    

参考文章

  1. 前台解决Json数据中出现”$ref”的问题
  2. 加上FastJsonHttpMessageConverter之后,前端获取不到数据
  3. fastjson在使用hibernate关系模型转json出现$ref解决办法
  4. 在springmvc中解决FastJson循环引用的问题