如何使用 Spring Cloud Netflix Feign 设置自定义 Jackson ObjectMapper
Posted
技术标签:
【中文标题】如何使用 Spring Cloud Netflix Feign 设置自定义 Jackson ObjectMapper【英文标题】:How to set custom Jackson ObjectMapper with Spring Cloud Netflix Feign 【发布时间】:2016-06-21 14:28:59 【问题描述】:我遇到了一种情况,我需要为第三方 API 定义一次性的 @FeignClient。在这个客户端中,我想使用与我的@Primary 不同的自定义 Jackson ObjectMapper。我知道可以覆盖 spring 的 feign 配置默认值,但是我不清楚如何仅通过这个特定的客户端简单地覆盖 ObjectMapper。
【问题讨论】:
你试过了还是不行? Spring Cloud Feign 使用与 Spring MVC 相同的HttpMessageConverters
对象。以正常的 Spring Boot 方式配置它应该“正常工作”(以为我自己没有尝试过)。 docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/…
@spencergibb 我可以覆盖 ObjectMapper,它被所有 Spring MVC 控制器和所有 Feign 客户端正确使用。但是,我需要一个特定的 feign 客户端,在众多客户端中,使用与默认配置的对象映射器不同的对象映射器。我什至不知道如何开始做这项工作。
你必须使用之前发布的文档链接创建一个SpringDecoder
bean,然后在那里搞砸。
@spencergibb,我开始工作,如下面的答案所示。谢谢你的帮助。
【参考方案1】:
根据documentation,您可以为您的 Feign 客户端提供自定义解码器,如下所示。
Feign 客户端接口:
@FeignClient(value = "foo", configuration = FooClientConfig.class)
public interface FooClient
//Your mappings
Feign 客户端自定义配置:
@Configuration
public class FooClientConfig
@Bean
public Decoder feignDecoder()
HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter(customObjectMapper());
ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(jacksonConverter);
return new ResponseEntityDecoder(new SpringDecoder(objectFactory));
public ObjectMapper customObjectMapper()
ObjectMapper objectMapper = new ObjectMapper();
//Customize as much as you want
return objectMapper;
【讨论】:
简单地为我工作return new JacksonDecoder(customObjectMapper());
【参考方案2】:
关注@NewBie 的回答,我可以给出更好的答案...
@Bean
public Decoder feignDecoder()
return new JacksonDecoder();
如果你想在feign客户端使用jackson消息转换器,请使用JacksonDecoder,因为SpringDecoder会增加feignclient调用的平均延迟在生产中。
<!-- feign-jackson decoder -->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-jackson</artifactId>
<version>10.1.0</version>
</dependency>
【讨论】:
依赖是什么?和版本?您可以为此显示 pom.xml 条目吗? 你能以百分比或毫秒或其他方式量化延迟的增加吗?我想要一个参考点来了解这有多大的不同。不过看起来很干净。 在我的印象中进步很大,生产中 8k qps 平均提高了 10 毫秒。【参考方案3】:@NewBie 的回答存在严重的性能问题。在new HttpMessageConverters
过程中,会执行loadclass,导致大量线程阻塞。如果您使用过此代码,请修改如下:
ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(jacksonConverter);
改成
HttpMessageConverters httpMessageConverters = new HttpMessageConverters(jacksonConverter);
ObjectFactory<HttpMessageConverters> objectFactory = () -> httpMessageConverters;
你可以使用JMeter和Arthas来重现这个现象,修改后的程序有了很大的改进。
【讨论】:
【参考方案4】:定义一个自定义解码器如下,注解@Configuration
并设置为feign客户端接口的参数configuration = CustomFeignClientConfig.class
@Configuration
public class CustomFeignClientConfig
@Bean
public Decoder feignDecoder()
return (response, type) ->
String bodyStr = Util.toString(response.body().asReader(Util.UTF_8));
JavaType javaType = TypeFactory.defaultInstance().constructType(type);
return new ObjectMapper().readValue( bodyStr, javaType);
;
【讨论】:
以上是关于如何使用 Spring Cloud Netflix Feign 设置自定义 Jackson ObjectMapper的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 AWS Beanstalk 和 Spring Cloud Netflix 在 Docker 容器之间建立连接
Spring Cloud Netflix—使用EurekaClient
Netflix之后,如何用Spring Cloud 新组件构建微服务架构?
将 apache kafka 与 Spring Cloud netflix 堆栈一起使用
spring-cloud-starter-eureka-server 和 spring-cloud-starter-netflix-eureka-server的区别