gpt4 book ai didi

java - RestTemplateBuilder 中的消息转换器重复?

转载 作者:行者123 更新时间:2023-12-02 01:34:00 24 4
gpt4 key购买 nike

我将 spring-bootspring-webjackson 一起使用。

问题:当 Spring 自动初始化 RestTemplate 时,构造函数会收到一些重复的 MessageConverters:

org.springframework.http.converter.ByteArrayHttpMessageConverter@6a1b4854,
org.springframework.http.converter.StringHttpMessageConverter@2d5b549b,
org.springframework.http.converter.StringHttpMessageConverter@6a175162,
org.springframework.http.converter.ResourceHttpMessageConverter@7641c4e7,
org.springframework.http.converter.ResourceRegionHttpMessageConverter@650a0b50,
org.springframework.http.converter.xml.SourceHttpMessageConverter@55e3b64d,
org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter@52f71d2,
org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@f3c27e9,
org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@7d31fb6c,
org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter@701c413,
org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter@48543f11

你看,有 3 个重复项:

StringHttpMessageConverter
MappingJackson2HttpMessageConverter
MappingJackson2XmlHttpMessageConverter

由于我自己没有初始化任何消息转换器:为什么应用程序上下文包含重复的转换器,然后将其添加到其余模板中?

特别是:如果某些转换器出现重复(但配置不同),这不会混淆(反)序列化吗?

例如:第一个MappingJackson2HttpMessageConverterObjectMapper包含更多registeredModuleTypes [Jdk8Module, JavaTimeModule, ParamterNamesModule, JsonComponentModule, GeoModule] 比第二个(仅包含:[Jdk8Module, JavaTimeModule])。

这有意义吗?

它是通过 RestTemplateAutoConfiguration.restTemplateBuilder() 实例化的,所有重复的 MessageConverters 都已存在。

最佳答案

罪魁祸首就在这里,在HttpMessageConverters

public HttpMessageConverters(boolean addDefaultConverters,
Collection<HttpMessageConverter<?>> converters) {
List<HttpMessageConverter<?>> combined = getCombinedConverters(converters,
addDefaultConverters ? getDefaultConverters() : Collections.emptyList());
combined = postProcessConverters(combined);
this.converters = Collections.unmodifiableList(combined);
}

具体来说,这一行(已格式化)

List<HttpMessageConverter<?>> combined = 
getCombinedConverters(
converters,
addDefaultConverters
? getDefaultConverters()
: Collections.emptyList());

converters 集合包含扫描的 HttpMessageConverter
基于环境。

enter image description here

然后将该列表与 WebMvcConfigurationSupport 提供的默认列表结合起来

enter image description here

public class WebMvcConfigurationSupport implements ApplicationContextAware, ServletContextAware {
private static final boolean romePresent;
private static final boolean jaxb2Present;
private static final boolean jackson2Present;
private static final boolean jackson2XmlPresent;
private static final boolean jackson2SmilePresent;
private static final boolean jackson2CborPresent;
private static final boolean gsonPresent;
private static final boolean jsonbPresent;
...

事实上,WebMvcConfigurationSupport 的文档说明了

This class registers ... ... a range of HttpMessageConverters depending on the third-party libraries available on the classpath.

通过HttpMessageConvertersAutoConfiguration找到并实例化扫描的HttpMessageConverter,其文档为

Auto-configuration for HttpMessageConverters.

该类本身公开了一个StringHttpMessageConverter

@Bean
@ConditionalOnMissingBean
public StringHttpMessageConverter stringHttpMessageConverter() {
StringHttpMessageConverter converter = new StringHttpMessageConverter(
this.properties.getCharset());
converter.setWriteAcceptCharset(false);
return converter;
}

然后,它导入 Jackson 或 Gson 自动配置

@Import({ 
JacksonHttpMessageConvertersConfiguration.class
GsonHttpMessageConvertersConfiguration.class,
JsonbHttpMessageConvertersConfiguration.class
})

这就是那些基于环境的“求和”到预定义的的方式。

<小时/>

Spring 不会因重复而感到困惑,因为它只采用第一个兼容的。
了解如何选择 HttpMessageConverter

enter image description here

你可以看到这只是一个简单的 for 循环,每个转换者都被要求说“我可以这样做吗?”通过 canWrite 方法

enter image description here

选择第一个有效的。

关于java - RestTemplateBuilder 中的消息转换器重复?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55517750/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com