13

我遇到了一种情况,我需要为第三方 API 定义一次性的 @FeignClient。在这个客户端中,我想使用与我的@Primary 不同的自定义 Jackson ObjectMapper。我知道可以覆盖 spring 的 feign 配置默认值,但是我不清楚如何仅通过这个特定的客户端简单地覆盖 ObjectMapper。

4

4 回答 4

37

根据文档,您可以为您的 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());

        HttpMessageConverters httpMessageConverters = new HttpMessageConverters(jacksonConverter);
        ObjectFactory<HttpMessageConverters> objectFactory = () -> httpMessageConverters;


        return new ResponseEntityDecoder(new SpringDecoder(objectFactory));
    }

    public ObjectMapper customObjectMapper(){
        ObjectMapper objectMapper = new ObjectMapper();
        //Customize as much as you want
        return objectMapper;
    }
}
于 2016-03-09T05:21:51.420 回答
8

follow @NewBie`s answer, i can give the better one...

  @Bean
  public Decoder feignDecoder() {
    return new JacksonDecoder();
  }

if you want use jackson message converter in feign client, please use JacksonDecoder, because SpringDecoder will increase average latency of feignclient call in production.

    <!-- feign-jackson decoder -->
    <dependency>
      <groupId>io.github.openfeign</groupId>
      <artifactId>feign-jackson</artifactId>
      <version>10.1.0</version>
    </dependency>
于 2019-07-08T02:33:21.433 回答
0

@NewBie 的回答存在严重的性能问题。在此new HttpMessageConverters过程中,会执行loadclass,导致大量线程阻塞。如果您使用过此代码,请修改如下:

ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(jacksonConverter);

改成

HttpMessageConverters httpMessageConverters = new HttpMessageConverters(jacksonConverter);
ObjectFactory<HttpMessageConverters> objectFactory = () -> httpMessageConverters;

可以使用JMeter和Arthas来重现这种现象,修改后的程序有了很大的改进。

于 2021-09-19T07:55:47.223 回答
0

如下定义一个自定义解码器,注释@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);
        };
    }
}
于 2021-08-04T07:40:55.323 回答