首页 > 解决方案 > SpringBoot中如何给FeignClient添加自定义拦截器

问题描述

在 RestTemplate 我有一个自定义拦截器,它将记录一些请求响应详细信息并保存到数据库。

我的自定义拦截器:

import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;

@Component
public class LogServices implements ClientHttpRequestInterceptor {
    
    @Override
    public ClientHttpResponse intercept(final HttpRequest request, final byte[] body, final ClientHttpRequestExecution execution) throws IOException {
        final String uri = request.getURI().toString();
        final ClientHttpResponse response = execution.execute(request, body);
        //log request response details and save to database
        return response;

springboot中的RestTemplate bean配置:

@Bean
public RestTemplate restTemplate(final RestTemplateBuilder restTemplateBuilder) {
  return restTemplateBuilder
  .setConnectTimeout(Duration.ofMillis(connectTimeout))
  .setReadTimeout(Duration.ofMillis(readTimeout))
  .build();

将拦截器添加到 restTemplate bean:

@Configuration
public class LogInterceptorConfiguration {
  @Autowired
  public void configureLogger(final RestTemplate restTemplate, final LogServices logServices) {
    final var interceptors = restTemplate.getInterceptors();
    interceptors.add(logServices);
    restTemplate.setInterceptors(interceptors);
  }

如何将此拦截器添加到 FeignClient?

在 application.yml 中:

feign:
  client:
    config:
      default:
        connectTimeout: 5000
        readTimeout: 5000
        request-interceptors[0]: com.api.restclient.InterceptorOne
        request-interceptors[1]: com.api.log.LogServices

InterceptorOne 为 feign 客户端中的每个请求添加一个标头:

@Configuration
public class InterceptorOne implements RequestInterceptor {
  @Override
  public void apply(RequestTemplate requestTemplate) {
     requestTemplate.header("some-header", "value");
  }

但我无法添加LogServices拦截器,因为它由于错误而不起作用cannot be cast to class feign.RequestInterceptor

我的猜测是我要添加的拦截器是通用拦截器,而不是专门的请求拦截器。所以我想知道如何向 FeignClient 添加一个类似于 RestTemplate 的通用拦截器

标签: spring-bootspring-cloud-feign

解决方案


您可以添加多个拦截器,如下所示

feign:
  client:
    config:
      feignName:
        connectTimeout: 5000
        readTimeout: 5000
        loggerLevel: full
        errorDecoder: com.example.SimpleErrorDecoder
        retryer: com.example.SimpleRetryer
        requestInterceptors:
          - com.example.InterceptorOne
          - com.example.LogServices
        decode404: false
        encoder: com.example.SimpleEncoder
        decoder: com.example.SimpleDecoder
        contract: com.example.SimpleContract

推荐阅读