欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 创投人物 > Spring boot 2.0 升级到 3.3.1 的相关问题 (四)

Spring boot 2.0 升级到 3.3.1 的相关问题 (四)

2025/9/21 16:12:48 来源:https://blog.csdn.net/weixin_48990070/article/details/140497010  浏览:    关键词:Spring boot 2.0 升级到 3.3.1 的相关问题 (四)

文章目录

    • Jackson的配置问题
      • 问题介绍
        • `MappingJackson2HttpMessageConverter` 没有默认编码的问题
        • 自定义`com.fasterxml.jackson.databind.Module` bean 不生效的问题
      • 问题解决
        • 方案1
        • 方案2
        • 方案3 (不可行)
      • 相关资料
        • `MappingJackson2HttpMessageConverter` 转换器构造流程
        • 其他

#Spring boot 2.0 升级到 3.3.1 的相关问题 (四)

Jackson的配置问题

问题介绍

MappingJackson2HttpMessageConverter 没有默认编码的问题

在Spring Boot 3.3.1 自定配置创建的MappingJackson2HttpMessageConverter 默认是没有指定字符串编码,因此在实际的使用中会自动使用ISO8859-1的编码。

StringHttpMessageConverter 默认编码为ISO8859-1,这个也需要修改。

自定义com.fasterxml.jackson.databind.Module bean 不生效的问题

由于Spring 自动配置的MappingJackson2HttpMessageConverter 创建时并不会使用配置的com.fasterxml.jackson.databind.Module ,因此会导致原型2.0版本通过该方式配置的JSON自定义序列化和反序列化无效。

问题解决

方案1

增加一个配置类实现WebMvcConfigurer 接口,并实现configureMessageConverters 或者extendMessageConverters 方法。这个两个方法都会将当前的系统中的所有MessageConverters传入。区别在于extendMessageConverters是做后置加工的,也就是到执行它的时候,系统内的MessageConverters已经是被前置处理过的(前置操作包括合并、排序等),而configureMessageConverters是没有被前置处理,甚至是部分的MessageConverters

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import java.nio.charset.StandardCharsets;
import java.util.List;/*** 自定义的Mvc配置,用于配置转换器*/
@Configuration
public class CustomWebMvcConverterConfigurer implements WebMvcConfigurer {@Autowiredprivate com.fasterxml.jackson.databind.Module customJackSonModule;/*** 扩展消息转换器列表,以支持自定义的字符集和Jackson模块。* 此方法遍历给定的消息转换器列表,并对特定类型的转换器应用自定义配置。* 具体来说,它将字符串转换器的默认字符集设置为UTF-8,并为Jackson转换器注册一个自定义的Jackson模块。** @param converters 消息转换器的列表,这里我们将遍历这个列表并对特定的转换器进行配置。*/@Overridepublic void extendMessageConverters(List<HttpMessageConverter<?>> converters) {// 遍历给定的消息转换器列表for(HttpMessageConverter<?> converter : converters) {// 如果当前转换器是字符串转换器,则将其默认字符集设置为UTF-8if(converter instanceof StringHttpMessageConverter stringHttpMessageConverter) {stringHttpMessageConverter.setDefaultCharset(StandardCharsets.UTF_8);continue;}// 如果当前转换器是Jackson 2转换器,则将其默认字符集设置为UTF-8,并注册自定义的Jackson模块if(converter instanceof MappingJackson2HttpMessageConverter jackson2HttpMessageConverter) {jackson2HttpMessageConverter.setDefaultCharset(StandardCharsets.UTF_8);ObjectMapper objectMapper = jackson2HttpMessageConverter.getObjectMapper();// 注册自定义的Jackson模块,以支持额外的序列化和反序列化需求objectMapper.registerModule(customJackSonModule);}}}}
方案2

直接在创建一个MappingJackson2HttpMessageConverter Bean。


import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;import java.nio.charset.StandardCharsets;@Configuration
public class JacksonConfiguration {@Autowiredprivate com.fasterxml.jackson.databind.Module customJackSonModule;@Beanpublic MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(ObjectMapper objectMapper) {MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();// 注册自定义ModuleobjectMapper.registerModule(customJackSonModule);converter.setObjectMapper(objectMapper);//默认字符集设置为UTF-8converter.setDefaultCharset(StandardCharsets.UTF_8);return converter;}
}   }
}
方案3 (不可行)

自定义Jackson2ObjectMapperBuilderCustomizer ,用于配置Jackson2ObjectMapperBuilder

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;/*** 配置Jackson2ObjectMapperBuilderCustomizer */
@Configuration
public class JacksonConfiguration {@Autowiredprivate com.fasterxml.jackson.databind.Module customJackSonModule;@Beanpublic Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperBuilderCustomizer() {return new Jackson2ObjectMapperBuilderCustomizer() {@Overridepublic void customize(Jackson2ObjectMapperBuilder builder) {// 注册自定义的 Modulebuilder.modulesToInstall(customJackSonModule);}};}
}

该方案不可行的原因是Spring Boot自动配置的MappingJackson2HttpMessageConverter 使用的ObjectMapper就没使用Jackson2ObjectMapperBuilder 的Bean去创建的,而是每次都重新创建一个Jackson2ObjectMapperBuilder的创建的。 这个应该是给未来版本来解决的,详情可以看org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration 这个类。

相关资料

MappingJackson2HttpMessageConverter 转换器构造流程

几个构造流程:
1、org.springframework.boot.autoconfigure.BackgroundPreinitializerorg.springframework.boot.autoconfigure.BackgroundPreinitializer.MessageConverterInitializer 初始化AllEncompassingFormHttpMessageConverter 消息转换器。在这个消息转换器中默认会初始化一堆消息转换器,其中就包含MappingJackson2HttpMessageConverter的无参构造方法。

2、org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration#formContentFilter 方法中创建了一个OrderedFormContentFilter 的Filter,这个Filter中默认会创建一个AllEncompassingFormHttpMessageConverter 消息转换器。在这个消息转换器中默认会初始化一堆消息转换器,其中就包含MappingJackson2HttpMessageConverter的无参构造方法。

AllEncompassingFormHttpMessageConverter 只处理Form 表单请求(请求头为application/x-www-form-urlencoded)的转换。

3、org.springframework.boot.autoconfigure.http.JacksonHttpMessageConvertersConfiguration.MappingJackson2HttpMessageConverterConfiguration#mappingJackson2HttpMessageConverter ,使用指定的ObjectMapper创建了一个MappingJackson2HttpMessageConverter

4、org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#requestMappingHandlerAdapter -> org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#getMessageConverters ->
org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#addDefaultHttpMessageConverters 使用默认的Jackson2ObjectMapperBuilder的配置创建一个MappingJackson2HttpMessageConverter

5、org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration#messageConverters

其他

默认的Jackson2ObjectMapperBuilderCustomizer 的实现
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration.Jackson2ObjectMapperBuilderCustomizerConfiguration.StandardJackson2ObjectMapperBuilderCustomizer

HttpMessageConverterwrite 方法调用点
org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor#writeWithMessageConverters(T, org.springframework.core.MethodParameter, org.springframework.http.server.ServletServerHttpRequest, org.springframework.http.server.ServletServerHttpResponse)

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词