在使用 Springboot 的 RestClient 类时,我需要能够覆盖 MappingJackson2HttpMessageConverter 的默认 ObjectMapper 依赖项(及其默认配置)。并非我与之交互的每个第 3 方 API 都符合 Springboot 似乎强加的默认配置。我能够使用以下代码成功覆盖默认的 ObjectMapper,但我想知道是否有更好、更明显的方法来实现此目的。我觉得很奇怪,更改 RestClient 使用的默认 ObjectMapper 是如此困难。
@Bean("torii")
public RestClient toriiApi(ObjectMapper objectMapper) {
return RestClient.builder()
.messageConverters(this::initMessageConverters)
.baseUrl(toriiApiHost)
.defaultHeader("Authorization", generateBasicAuthHeaderValue(torriApiBasicAuthUser, torriApiBasicAuthPassword))
.defaultHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE)
.defaultHeader("Accepted", MediaType.APPLICATION_JSON_VALUE)
.build();
}
private void initMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
AtomicInteger counter = new AtomicInteger();
AtomicReference<Integer> jacksonConvertIndex = new AtomicReference<>();
messageConverters.forEach(httpMessageConverter -> {
if (httpMessageConverter instanceof MappingJackson2HttpMessageConverter) {
jacksonConvertIndex.set(counter.get());
}
counter.getAndIncrement();
});
messageConverters.remove(jacksonConvertIndex.get().intValue());
messageConverters.add(new MappingJackson2HttpMessageConverter(objectMapper));
}
您可以在现有的
MappingJackson2HttpMessageConverter
上设置objectMapper,因为它有一个公共setter,继承自AbstractJackson2HttpMessageConverter
:
private void initMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
messageConverters.forEach(httpMessageConverter -> {
if (httpMessageConverter instanceof MappingJackson2HttpMessageConverter jacksonConverter) {
jacksonConverter.setObjectMapper(objectMapper);
}
});
}
除了这个调整之外,我认为在您的情况下这是对 API 的适当使用,我假设您希望保留所有默认消息转换器并且仅更改
MappingJackson2HttpMessageConverter
- RestClient.Builder#messageConverters
的参数称为 configurer
所以看来预计会改变列表。
您可能更喜欢使用
RestClient.builder(RestTemplate)
重载并在 RestTemplate 上设置 messageConverters,但如果您想保留使用稍作修改的默认列表的功能,您最终会在 RestTemplate 上使用 messageConverters 执行相同的操作休息模板。如果您不关心保留 MessageConverters 的其余部分,那么您可以将 RestTemplate 与您想要的单个MappingJackson2HttpMessageConverter
一起使用。