1.问题描述
后端返回前端接口数据包含引用数据,如下图所示
2.原因
转json时使用这种方式,fastjson自动使用循环引用:
String content = JSONObject.toJSONString(object);
3.fastjson的循环引用
当一个对象包含另一个对象时,fastjson就会把该对象解析成引用。引用是通过$ref标示的,下面介绍一些引用的描述
"$ref":".." 上一级
"$ref":"@" 当前对象,也就是自引用
"$ref":"$" 根对象
"$ref":"$.children.0" 基于路径的引用,相当于 root.getChildren().get(0)
4.解决方案
对象转为json
String content = JSONObject.toJSONString(object, SerializerFeature.DisableCircularReferenceDetect);
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>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)