SpringCloud组件OpenFeign——拦截器

OpenFeign组件中有这么一个接口——RequestInterceptor 。我们来看一下源码中关于这个接口的介绍。

package feign;

/**
 * 可以配置零个或多个请求拦截器,可以用于例如给所有请求添加请求头信息.但是不能保证拦截器的应用顺 
 * 序。一旦拦截器被应用,就会调用Target类中的apply(RequestTemplate)方法去创建不可变的http请 
 * 求,该请求通过Client类中的execute(Request, feign.Request.Options)发送。
 *
 * 拦截器是在设置rest模板参数后才被应用的,因此不能再拦截器中添加参数,比如不能再    
 * apply(RequestTemplate)方法中给/path/{foo}/bar中的foo设置参数。

 * 这个类类似于RequestInterceptor.intercept()方法,可以实现读取、删除或以其他方式改变请求模板 
 * 的任何部分。
 */
public interface RequestInterceptor {

  /**
   * 可以被每个请求调用。使用RequestTemplate提供的这个方法可以添加数据。
   */
  void apply(RequestTemplate template);
}

通过对该类及方法的注释可以了解到RequestInterceptor接口的apply方法可以对请求进行拦截,可以在该方法中添加请求头信息。

实践一下。

一、创建一个拦截器在请求头中添加traceId信息

场景如下,使用拦截器在请求头中添加traceId属性,服务端可以获取到该traceId,用于日志追踪。

方式一:创建自定义拦截器+@Configuration

package com.example.rtbootconsumer.config.interceptor;

import com.example.rtbootconsumer.common.utils.TraceIdUtil;
import feign.Request;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Configuration;

/**
 * @Description Feign接口请求拦截器
 **/
@Configuration
public class FeignRequestInterceptor implements RequestInterceptor {

    /**
     * @description: 将traceId设置到请求头
     */
    @Override
    public void apply(RequestTemplate template) {
        String traceId = TraceIdUtil.getTraceId();
        if (StringUtils.isNotEmpty(traceId)) {
            template.header("traceId", traceId);
        }
    }
}

方式二:创建自定义拦截器+配置@FeignClient注解的configuration属性

package com.example.rtbootconsumer.config.interceptor;

import com.example.rtbootconsumer.common.utils.TraceIdUtil;
import feign.Request;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Configuration;

/**
 * @Description Feign接口请求拦截器
 **/
public class FeignRequestInterceptor implements RequestInterceptor {

    /**
     * @description: 将traceId设置到请求头
     */
    @Override
    public void apply(RequestTemplate template) {
        String traceId = TraceIdUtil.getTraceId();
        if (StringUtils.isNotEmpty(traceId)) {
            template.header("traceId", traceId);
        }
    }
}
package com.example.rtbootconsumer.feignservice;

import com.example.rtbootconsumer.pojo.User;
import com.example.rtbootconsumer.vo.ResultBody;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;

import java.util.List;


@FeignClient(name = "service-provider", path = "/testComm", url = "${addr.url}",configuration = FeignRequestInterceptor.class)
public interface UserFeignService {

    @PostMapping(value = "/getUser")
    public ResultBody<User> getUser(@RequestBody User user);
}

二、创建两个拦截器

也可以同时创建多个拦截器实现拦截器链的功能。

此时再创建一个拦截器FeignRequestInterceptor2,用于在请求头中设置属性名为test,值为lalala信息。

方式一:同上

package com.example.rtbootconsumer.config.interceptor;

import com.example.rtbootconsumer.common.utils.TraceIdUtil;
import feign.Request;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Configuration;

/**
 * @Description Feign接口请求拦截器
 **/
@Configuration
public class FeignRequestInterceptor2 implements RequestInterceptor {

    /**
     * @description: 将test设置到请求头
     */
    @Override
    public void apply(RequestTemplate template) {
        String traceId = TraceIdUtil.getTraceId();
        if (StringUtils.isNotEmpty(traceId)) {
            template.header("test", "lalala");
        }
    }
}

方式二:同上,注意这里设置的@FeignClient注解的configuration属性值是两个拦截器的class数组。

package com.example.rtbootconsumer.feignservice;

import com.example.rtbootconsumer.pojo.User;
import com.example.rtbootconsumer.vo.ResultBody;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;

import java.util.List;


@FeignClient(name = "service-provider", path = "/testComm", url = "${addr.url}",configuration = {FeignRequestInterceptor.class,FeignRequestInterceptor2.class})
public interface UserFeignService {

    @PostMapping(value = "/getUser")
    public ResultBody<User> getUser(@RequestBody User user);

    @PostMapping(value = "/testList")
    public ResultBody<List<User>> testList(@RequestBody List<User> list);
}

三、注意

在创建并配置拦截器时有两点需要特别注意。

  1. 在使用方式一去创建拦截器时,会拦截所有请求。用方式二时若@FeignClient注解的configuration属性未设置拦截器,那么并不会拦截该接口下所有方法的请求。拦截器只会拦截所有configuration属性值设置了拦截器的接口下所有方法的请求。因此使用方式二更灵活。
  2. 拦截器执行顺序。若使用方式一去创建多个拦截器时,正如前面注释所讲,不能保证拦截器的执行顺序。但是使用方式二则可以控制拦截器的执行顺序,拦截器的执行顺序和@FeignClient注解中configuration属性中拦截器的配置顺序有关。若配置为 {FeignRequestInterceptor.class,FeignRequestInterceptor2.class}),则会先执行FeignRequestInterceptor中的拦截,再执行FeignRequestInterceptor2中的拦截。若配置为 {FeignRequestInterceptor2.class,FeignRequestInterceptor.class}),则会先执行FeignRequestInterceptor2中的拦截,再执行FeignRequestInterceptor中的拦截。有兴趣的可以试一下。
  • 9
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要配置Feign拦截器,你可以使用两种方式。 第一种方式是创建一个拦截器类并实现RequestInterceptor接口。你可以自定义一个拦截器类,例如CustomFeignInterceptor,并在apply方法中实现你需要的功能,比如记录日志、增加参数修改路径或鉴权。然后,在你的微服务的config配置中将该拦截器作为Bean注入,如下所示: ``` @Configuration public class FeignConfig { @Bean public RequestInterceptor requestInterceptor(){ return new CustomFeignInterceptor(); } } ``` 接着,在需要使用该功能的Client接口上的@FeignClient()内加上configuration = FeignConfig.class参数,以交给Spring管理,示例如下: ``` @FeignClient(value ="itemservice",path = "/item",configuration = FeignConfig.class) public interface ItemClient { @GetMapping("/list") public PageDTO<Item> page(@RequestParam("page") Integer page, @RequestParam("size") Integer size); @GetMapping("/{id}") public Item getById(@PathVariable Long id); } ``` 另一种配置方式是直接注入拦截器的Bean。在你的配置类中,可以使用@Bean注解创建一个CustomFeignInterceptor的Bean,如下所示: ``` @Bean public CustomFeignInterceptor customFeignInterceptor(){ return new CustomFeignInterceptor(); } ``` 记得在需要使用该功能的Client接口上的@FeignClient()内加上configuration参数,指定使用该拦截器的Bean,例如: ``` @FeignClient(value ="itemservice",path = "/item",configuration = YourConfigClass.class) public interface ItemClient { // API methods } ``` 这样,你就可以配置Feign拦截器了。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [SpringCloudOpenFeign 自定义配置和使用/自定义拦截器](https://blog.csdn.net/weixin_44137464/article/details/127325544)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [Feign的权限访问(拦截器)](https://blog.csdn.net/weixin_52472963/article/details/129309826)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luffylv

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值