热搜: fiddler git ip 代理
历史搜索

解决easyUI中使用fastjson时出现$ref: “$.[0]“

游客2024-12-20 07:53:01
目录文章目录
  1. 一、问题分析:$ref:
  2. 二、循环引用和重复引用
  3. 三、$ref 问题的解决方案:

解决easyUI中使用fastjson时出现$ref: “$.[0]“ 1

这里就是循环引用造成的。

一、问题分析:$ref:

  1. 接口返回的api通过fastjson将实体转化为json字符串时,在传输的数据中如果出现相同的对象,fastjson默认开启引用检测会将相同的对象写成引用的形式;
  2. 引用是通过 $ref 来表示的 引用分两种;
  3. 循环引用和重复引用。
占位符 类型
“$ref”:”..” 上一级
“$ref”:”@” 当前对象,也就是自引用
“$ref”:”$” 根对象
“$ref”:”$.children.0″ 基于路径的引用,相当于 root.getChildren().get(0)

二、循环引用和重复引用

循环引用:即 A 对象引用 B 对象,B 对象又引用 A 对象,这种情况是要极力避免的,因为会导致堆栈溢出 (StackOverflowError)

三、$ref 问题的解决方案:

1. 局部关闭

将该对象在后端转换为 json 字符串返回给前端,使用 SerializerFeature.DisableCircularReferenceDetect关闭循环引用。

String str=JSON.toJSONString(object,SerializerFeature.DisableCircularReferenceDetect);

正常来说,我们的接口返回给前端的是 List 这种格式,如果采用这个方式,就要将返回值改为 String,不 优雅。当然也可以把这个字符串再次转换为对象,这样循环引用的问题就没有了。

2. spring boot 项目

public class FastJsonHttpMessageConverterEx extends
FastJsonHttpMessageConverter{
    public FastJsonHttpMessageConverterEx(){
        //在这里配置 fastjson 特性(全局设置的)
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        //fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss"); //自定义时间格式
        //fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteMapNullValue);
        //正常转换 null 值
        fastJsonConfig.setSerializerFeatures(SerializerFeature.DisableCircularReference
Detect);                 
        //关闭循环引用
        this.setFastJsonConfig(fastJsonConfig);
}
 
@Override
    protected boolean supports(Class<?> clazz) {
        return super.supports(clazz);
    }
}
@Configuration
public class WebMvcConfigurer extends WebMvcConfigurerAdapter {
        .....
    @Bean
    public FastJsonHttpMessageConverterEx fastJsonHttpMessageConverterEx(){
        return new FastJsonHttpMessageConverterEx();
    }
}

3. 禁止序列化

如果循环引用的数据,前端用不到,那可以在实体类对应的字段加注解禁止序列化,这样前端就不会接 收到这个字段的引用数据了。

@JSONField(serialize = false)
private List<Dept> dept

4. 普通 spring 项目

全局关闭循环引用检查:

<!-- 全局关闭循环引用检查,最好是不要关闭,不然有可能会 StackOverflowException -->
<value>DisableCircularReferenceDetect</value>

在该字段的注解上指定序列化时关闭循环引用

//一个员工对应一个部门表
@JSONField(serialzeFeatures =
SerializerFeature.DisableCircularReferenceDetect)
private Dept dept=new Dept()

此种方法才是我们项目中的解决办法。

标签:$ref