[SpringBoot2.6.13]FastJsonHttpMessageConverter不生效

文章目录

    • 错误描述
    • 问题分析
      • 打印目前所有的消息处理器
      • 寻找适配版本
      • 消息解释器加载顺序
    • 错误原因
    • 正确写法
      • 使用最新版本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);
    }