问题描述:

今天在做后台传数据到前端解析的时候遇到了这个问题。背景介绍下:后台传过去json数据是用阿里的fastjson转换的,调用的是这个方法
String s = JSON.toJSONStringWithDateFormat(o,dateformat,SerializerFeature.WriteDateUseDateFormat);
ServletActionContext.getResponse().getWriter().write(s);
其中dataformat是格式化时间数据的。传过去的是一个PageBean对象,该对象继承了Page对象,Page里面包含list,pageNo,pageSize。前台在通过data.list准备取出list循环做点事情的时候,发现全是undefined,通过console.log(data.list),发现这个数据竟然是这个东西$ref: "$.list[0]"。百度搜了下,这里就是循环引用造成的。

问题分析:

循环引用:当一个对象包含另一个对象时,fastjson就会把该对象解析成引用。引用是通过$ref标示的,下面介绍一些引用的描述
  • "$ref":".." 上一级
  • "$ref":"@" 当前对象,也就是自引用
  • "$ref":"$" 根对象
  • "$ref":"$.children.0" 基于路径的引用,相当于 root.getChildren().get(0)

解决方案:

fastjson提供了多种json转换方案,有兴趣的同学可以自己看看源码,这里我们可以采用禁止循环引用的方案:
String s = JSON.toJSONStringWithDateFormat(0,"yyyy-MM-dd HH:mm:ss",SerializerFeature.DisableCircularReferenceDetect);
其中:SerializerFeature.DisableCircularReferenceDetect就是禁止循环引用的方案,我们可以通过枚举类SerializerFeature来查看到底有多少种方式:
public enum SerializerFeature {
    QuoteFieldNames,
    UseSingleQuotes,
    WriteMapNullValue,
    WriteEnumUsingToString,
    UseISO8601DateFormat,
    /**
     * @since 1.1
     */
    WriteNullListAsEmpty,
    /**
     * @since 1.1
     */
    WriteNullStringAsEmpty,
    /**
     * @since 1.1
     */
    WriteNullNumberAsZero,
    /**
     * @since 1.1
     */
    WriteNullBooleanAsFalse,
    /**
     * @since 1.1
     */
    SkipTransientField,
    /**
     * @since 1.1
     */
    SortField,
    /**
     * @since 1.1.1
     */
    @Deprecated
    WriteTabAsSpecial,
    /**
     * @since 1.1.2
     */
    PrettyFormat,
    /**
     * @since 1.1.2
     */
    WriteClassName,

    /**
     * @since 1.1.6
     */
    DisableCircularReferenceDetect,

    /**
     * @since 1.1.9
     */
    WriteSlashAsSpecial,
    
    /**
     * @since 1.1.10
     */
    BrowserCompatible,
    
    /**
     * @since 1.1.14
     */
    WriteDateUseDateFormat,
    
    /**
     * @since 1.1.15
     */
    NotWriteRootClassName,
    
    /**
     * @since 1.1.19
     */
    DisableCheckSpecialChar,
    
    /**
     * @since 1.1.35
     */
    BeanToArray
    ;

    private SerializerFeature(){
        mask = (1 << ordinal());
    }

    private final int mask;

    public final int getMask() {
        return mask;
    }

    public static boolean isEnabled(int features, SerializerFeature feature) {
        return (features & feature.getMask()) != 0;
    }

    public static int config(int features, SerializerFeature feature, boolean state) {
        if (state) {
            features |= feature.getMask();
        } else {
            features &= ~feature.getMask();
        }

        return features;
    }
}


GitHub 加速计划 / js / json
41.72 K
6.61 K
下载
适用于现代 C++ 的 JSON。
最近提交(Master分支:1 个月前 )
960b763e 3 个月前
8c391e04 6 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐