SpringDoc-OpenApi与Fastjson冲突——FastJsonHttpMessageConverter对String的默认处理
我的项目中默认是这样使用FastJsonHttpMessageConverter的:
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(
// 防止循环引用
SerializerFeature.DisableCircularReferenceDetect,
// 空集合返回[],不返回null
SerializerFeature.WriteNullListAsEmpty,
// 空字符串返回"",不返回null
SerializerFeature.WriteNullStringAsEmpty,
SerializerFeature.WriteMapNullValue
);
fastJsonConfig.getSerializeConfig().put(String.class,MyStringSerializer.instance);
fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig);
//处理中文乱码问题
List<MediaType> fastMediaTypes = new ArrayList<>();
fastMediaTypes.add(MediaType.APPLICATION_JSON);
fastJsonHttpMessageConverter.setSupportedMediaTypes(fastMediaTypes);
converters.add(0, fastJsonHttpMessageConverter);//放到前面
}
之前本来相安无视,后面因为springboot升级到2.6.x,原有的springfox因为很久没有更新出现兼容问题(虽然可以解决),再加上想尝试使用新的openapi3,因此换用了最近有在更新的springdoc-openapi。结果两者配合使用时,swagger界面无法加载,而v3/api-docs中的json都多出了\:
"{\"openapi\":\"3.0.1\",\"info\":{\"title\":\"OpenAPI definition\",\"version\":\"v0\"},\"servers\":[{\"url\":\"http://localhost:8099\",\"description\":\"Generated server url\"}],\"paths\":{},\"components\":{}}"
这直接导致swagger无法正确的识别,从而界面加载失败。而原来使用springfox时,并没有出现这个问题。
经过打断点分析,发现原来使用springfox时,传到com.alibaba.fastjson.serializer.SerializeConfig#getObjectWriter(java.lang.Class<?>, boolean)
这里时,class是springfox.documentation.spring.web.json.Json
,fastjson对此作了特殊处理,因此可以保持原样。而改换springdoc时,此处传入的class却是String! 而fastjson默认会对String进行处理,加上转义符号,因此导致最终的结果出现异常。
解决办法:
1、换成Jackson的converter(springboot默认就是Jackson)。
2、FastJsonHttpMessageConverter:自定义一个StringSerializer,覆盖掉fastjson的默认的StringSerializer
public class MyStringSerializer implements ObjectSerializer {
public static final MyStringSerializer instance = new MyStringSerializer();
@Override
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
SerializeWriter out = serializer.getWriter();
out.write(object.toString());
}
}
然后在FastJsonHttpMessageConverter的配置文件中,如下使用
fastJsonConfig.getSerializeConfig().put(String.class,MyStringSerializer.instance);
即可覆盖掉fastjson默认的StringSerializer。(也可以通过这么操作,对其它类进行自定义处理)。
因为理解不是很透彻,不清楚fastjson为什么默认要对String进行字符转义处理,也不太清楚这样修改是否会导致其他后果,如果不妥希望能指出。
(本bug已经提交到fastjson在github上的issues中,期望能得到解答,不过这个好像只能靠分析String里的内容来solve了...)
这个bug只有FastJsonHttpMessageConverter添加到converters最前面或在默认的Jackson之前时会引起这个问题,关于converters的顺序等更深入的探讨,可以参考这篇文章:
本文来自博客园,作者:JessieLin,转载请注明原文链接:https://www.cnblogs.com/6543x1/p/15816139.html