fastjson解析出现引用问题

1.问题描述

 后端返回前端接口数据包含引用数据,如下图所示

 2.原因

转json时使用这种方式,fastjson自动使用循环引用:

String content = JSONObject.toJSONString(object);
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

3.fastjson的循环引用

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

4.解决方案

对象转为json

String content = JSONObject.toJSONString(object, SerializerFeature.DisableCircularReferenceDetect);
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

json解析为对象,两个方式

1.全局配置

package com.flowpp.citylights.detection.config;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * ps: 不能同时存在WebMvcConfigurationSupport和WebMvcConfigurer
 * 否则会导致继承WebMvcConfigurationSupport的配置类失效
 *
 * @description mvc配置
 **/
@Component
public class WebMvcConfig extends WebMvcConfigurationSupport {

   
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {

        //先干掉jackson
        Iterator<HttpMessageConverter<?>> iterator = converters.iterator();
        while (iterator.hasNext()) {
            HttpMessageConverter<?> converter = iterator.next();
            if (converter instanceof MappingJackson2HttpMessageConverter) {
                iterator.remove();
            }
        }

        FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
        //自定义配置...
        FastJsonConfig config = new FastJsonConfig();
        config.setDateFormat("yyyy-MM-dd HH:mm:ss");
        config.setCharset(StandardCharsets.UTF_8);
        config.setSerializerFeatures(
        //禁止循环引用和重复引用
                SerializerFeature.DisableCircularReferenceDetect,
                SerializerFeature.WriteMapNullValue,
                SerializerFeature.PrettyFormat,
                SerializerFeature.WriteNullListAsEmpty,
                SerializerFeature.WriteNullStringAsEmpty
        );
        converter.setFastJsonConfig(config);

        List<MediaType> fastMediaType = new ArrayList<>();
        MediaType mediaType = MediaType.parseMediaType("text/html;charset=UTF-8");
        fastMediaType.add(mediaType);
        fastMediaType.add(MediaType.APPLICATION_JSON);
        converter.setSupportedMediaTypes(fastMediaType);

        converters.add(0, converter);
    }
}

2.局部配置

在属性上添加注解

    /**
     * 控制范围
     */
    @JSONField(serialzeFeatures = SerializerFeature.DisableCircularReferenceDetect)
    private List<Integer> controlRange;

 以上都配置完成了之后,我们项目仍然不生效,这是最让人纠结的事,为此郁闷了一天。翻看了网上所有资料,这种配置都没有问题,因此查看了fastjson的最新版本和项目中版本对比。一般会选择使用者较多且较新的版本。我们项目使用的是2.0.6版本,这个是dubbo-spring-boot-starter的2.7.8版本自动引用的,挺坑人的。换个fastjson的2.0.7版本就好使了。又是开心的一天~

      <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>2.0.7</version>
        </dependency>
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值