java - RestTemplateBuilder中重复的MessageConverters?
问题描述
我正在spring-boot
使用spring-web
和jackson
。
问题:当RestTemplate
spring 自动初始化 a 时,构造函数会收到一些重复的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
由于我自己没有初始化任何消息转换器:为什么应用程序上下文根本包含重复的转换器,然后将其添加到 resttemplate?
特别是:如果某些转换器出现重复(但配置不同),这不会混淆(反)序列化吗?
例如:ObjectMapper
第一个MappingJackson2HttpMessageConverter
包含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
的(S)。
基于环境。
然后将该列表与由提供的默认列表连接WebMvcConfigurationSupport
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;
...
InfactWebMvcConfigurationSupport
州的文件
这个类注册……一系列
HttpMessageConverters
取决于类路径上可用的第三方库。
扫描HttpMessageConverter
的(s)通过 找到并实例化HttpMessageConvertersAutoConfiguration
,其文档是
自动配置
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
选择an
你可以看到它只是一个简单的 for 循环,每个转换都被要求说“我可以这样做吗?” 通过canWrite
方法
选择第一个有效值。
推荐阅读
- java - BoxLayout can't be shared 错误,试图在一个 JFrame 中容纳两个 JPanel
- vba - VBA:如何获取当前 Outlook 用户的 SMTP 电子邮件地址列表?
- symfony - 获取 symfony 学说 findAll 以返回具有特定类型键的数组
- smtp - Plesk 服务器 (Centos) 上的 SMTP 配置
- python - 从 CSV 读取返回 IndexError: list index out of range
- count - Splunk 计算 2 个具有两个不同组的不同字段,而不显示它们
- google-app-maker - AppMaker:动态添加角色给用户
- hp-uft - 在 Chrome 浏览器中执行 UFT 脚本
- css - Bootstrap Carousel 控制大小
- java - 多个相同类型的@Embedded 字段在持久化后始终为空