文章目录
-
- 错误描述
- 问题分析
-
- 打印目前所有的消息处理器
- 寻找适配版本
- 消息解释器加载顺序
- 错误原因
- 正确写法
-
- 使用最新版本fastjson(2024-1-22)
- 配置fastjson2消息转换器(保留系统原消息转换器)
- 替换消息转换器配置fastjson2
错误描述
采用@Bean的方式配置FastJsonHttpMessageConverter消息解释器,实测在【SpringBoot2.6.13】未生效
但是在【SpringBoot2.1.4.RELEASE】版本中正常
2.1.4.RELEASE中引入如下
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.56</version> </dependency>
配置如下
import com.alibaba.fastjson.serializer.SerializeConfig; import com.alibaba.fastjson.serializer.SerializerFeature; import com.alibaba.fastjson.support.config.FastJsonConfig; import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; @Bean public HttpMessageConverters fastJsonHttpMessageConverters() { FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter(); FastJsonConfig fastJsonConfig = new FastJsonConfig(); fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss"); fastJsonConfig.setSerializerFeatures( SerializerFeature.PrettyFormat, SerializerFeature.QuoteFieldNames, SerializerFeature.WriteEnumUsingName, SerializerFeature.DisableCircularReferenceDetect ); List<MediaType> fastMediaTypes = new ArrayList<>(); fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8); fastConverter.setSupportedMediaTypes(fastMediaTypes); fastConverter.setFastJsonConfig(fastJsonConfig); return new HttpMessageConverters(fastConverter); }
问题分析
打印目前所有的消息处理器
通过打印消息处理器,发现配置并未成功
public class MvcConfig implements WebMvcConfigurer { @Override public void extendMessageConverters(List<HttpMessageConverter<?>> converters) { for (HttpMessageConverter<?> messageConverter : converters) { System.out.println(messageConverter); } } }
得到如下输出日志
org.springframework.http.converter.ByteArrayHttpMessageConverter@1ddf42dd org.springframework.http.converter.StringHttpMessageConverter@5c1c9881 org.springframework.http.converter.ResourceHttpMessageConverter@1c18ee69 org.springframework.http.converter.ResourceRegionHttpMessageConverter@2f99d8c org.springframework.http.converter.xml.SourceHttpMessageConverter@65d7eea4 org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter@5d37aa0f org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter@6076c66 org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@485c84d7
寻找适配版本
官网可知,fastjson早已停止更新,新版本需使用fastjson2
在 Spring 中集成 Fastjson2 | fastjson2 (alibaba.github.io)
引入如下
<dependency> <groupId>com.alibaba.fastjson2</groupId> <artifactId>fastjson2-extension-spring5</artifactId> <version>2.0.43</version> </dependency>
官网得到如下配置
@Configuration @EnableWebMvc public class WebMvcConfigurer extends WebMvcConfigurerAdapter { @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); //自定义配置... FastJsonConfig config = new FastJsonConfig(); config.setDateFormat("yyyy-MM-dd HH:mm:ss"); config.setReaderFeatures(JSONReader.Feature.FieldBased, JSONReader.Feature.SupportArrayToBean); config.setWriterFeatures(JSONWriter.Feature.WriteMapNullValue, JSONWriter.Feature.PrettyFormat); converter.setFastJsonConfig(config); converter.setDefaultCharset(StandardCharsets.UTF_8); converter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON)); converters.add(0, converter); } }
消息解释器加载顺序
需要将FastJsonHttpMessageConverter配置为第一位消息处理器才能得到输出
其测试过程如下
converters.add(converter);
此时得到输出为
org.springframework.http.converter.ByteArrayHttpMessageConverter@1ddf42dd org.springframework.http.converter.StringHttpMessageConverter@5c1c9881 org.springframework.http.converter.ResourceHttpMessageConverter@1c18ee69 org.springframework.http.converter.ResourceRegionHttpMessageConverter@2f99d8c org.springframework.http.converter.xml.SourceHttpMessageConverter@65d7eea4 org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter@5d37aa0f org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter@6076c66 org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@485c84d7 com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter@1224e1b6
实测未生效
{ "code": 200, "msg": "请求成功", "data": { "loginName": null, "userName": "柒杉", "userCode": null, "loginDate": 1705547281595 } }
修改为
converters.add(0, converter);
得到输出
com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter@2a667f44 org.springframework.http.converter.ByteArrayHttpMessageConverter@53ba7997 org.springframework.http.converter.StringHttpMessageConverter@3f6f9cef org.springframework.http.converter.ResourceHttpMessageConverter@61dd1c3d org.springframework.http.converter.ResourceRegionHttpMessageConverter@7858d31d org.springframework.http.converter.xml.SourceHttpMessageConverter@782e6b40 org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter@3b65084e org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter@32d0d7eb org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@cae2a97
错误原因
在高版本中需要采用最新的fastjson2配置
正确写法
使用最新版本fastjson(2024-1-22)
<dependency> <groupId>com.alibaba.fastjson2</groupId> <artifactId>fastjson2-extension-spring5</artifactId> <version>2.0.43</version> </dependency>
配置fastjson2消息转换器(保留系统原消息转换器)
@Override public void extendMessageConverters(List<HttpMessageConverter<?>> converters) { // 创建 FastJson 的消息转换器实例 FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); // 创建 FastJson 的配置实例 FastJsonConfig config = new FastJsonConfig(); // 设置时间类型日期格式 config.setDateFormat("yyyy-MM-dd HH:mm:ss"); config.setReaderFeatures( // 基于字段序列化,如果不配置,会默认基于public的field和getter方法序列化。 // 配置后,会基于非static的field(包括private)做序列化。 JSONReader.Feature.FieldBased, // 支持数据映射的方式 JSONReader.Feature.SupportArrayToBean ); config.setWriterFeatures( // 显示null与空字符串 // JSONWriter.Feature.WriteMapNullValue, // 格式化输出 JSONWriter.Feature.PrettyFormat, // 将Long序列化为String JSONWriter.Feature.WriteLongAsString ); // 将序列化配置设置到 FastJson 配置中 converter.setFastJsonConfig(config); converter.setDefaultCharset(StandardCharsets.UTF_8); // 创建一个媒体类型,表示支持 JSON 格式,并使用 UTF-8 编码 List<MediaType> fastMediaTypes = new ArrayList<>(); MediaType utf8MediaType = new MediaType(MediaType.APPLICATION_JSON, StandardCharsets.UTF_8); fastMediaTypes.add(utf8MediaType); converter.setSupportedMediaTypes(fastMediaTypes); // 将 FastJson 消息转换器添加到 Spring Boot 的消息转换器列表中,位置是第一个,这样确保它优先于其他消息转换器 converters.add(0, converter); }
替换消息转换器配置fastjson2
@Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { // 创建 FastJson 的消息转换器实例 FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); // 创建 FastJson 的配置实例 FastJsonConfig config = new FastJsonConfig(); // 设置时间类型日期格式 config.setDateFormat("yyyy-MM-dd HH:mm:ss"); config.setReaderFeatures( // 基于字段序列化,如果不配置,会默认基于public的field和getter方法序列化。 // 配置后,会基于非static的field(包括private)做序列化。 JSONReader.Feature.FieldBased, // 支持数据映射的方式 JSONReader.Feature.SupportArrayToBean ); config.setWriterFeatures( // 显示null与空字符串 // JSONWriter.Feature.WriteMapNullValue, // 格式化输出 JSONWriter.Feature.PrettyFormat, // 将Long序列化为String JSONWriter.Feature.WriteLongAsString ); // 将序列化配置设置到 FastJson 配置中 converter.setFastJsonConfig(config); converter.setDefaultCharset(StandardCharsets.UTF_8); // 创建一个媒体类型,表示支持 JSON 格式,并使用 UTF-8 编码 List<MediaType> fastMediaTypes = new ArrayList<>(); MediaType utf8MediaType = new MediaType(MediaType.APPLICATION_JSON, StandardCharsets.UTF_8); fastMediaTypes.add(utf8MediaType); converter.setSupportedMediaTypes(fastMediaTypes); // 将 FastJson 消息转换器添加到 Spring Boot 的消息转换器列表中,位置是第一个,这样确保它优先于其他消息转换器 converters.add(0, converter); }