当前位置: 首页 > news >正文

OpenFeign 自定义拦截器

假设现在有这么一个工程 mall4cloud,它有两个模块,order-openfeign、user。

order-openfeign 通过 feign 调用 user。

一、拦截器原理

OpenFeign 作为微服务间接口的调用组件,除了需要考虑传递消息体外,还需要考虑到如何在各个服务间传递请求头信息。如果不做任何配置,直接使用openFeign在服务间进行调用就会如下图:

这样会丢失请求头,在企业级的应用中,token 是非常重要的请求信息,他会携带权限、用户信息等。

OpenFeign 在远程调用之前会遍历容器中的 RequestInterceptor,调用 RequestInterceptor 的apply 方法,创建一个新的 Request 进行远程服务调用。因此可以通过实现 RequestInterceptor 给容器中添加自定义的 RequestInterceptor 实现类,在这个类里面设置需要发送请求时的参数,比如请求头信息,链路追踪信息等。

 ​​​​

package feign;public interface RequestInterceptor {void apply(RequestTemplate var1);
}

二、使用场景

通过拦截器实现参数传递。

常用场景:统一添加 header 信息。(比如服务提供者传递全局事务XID,会员ID,认证 token 令牌,链路追踪 traceID 等等)

三、模拟实现

3.1、自定义拦截器实现 RequestInterceptor 接口

@Slf4j
public class TokenAuthRequestInterceptor implements RequestInterceptor {@Overridepublic void apply(RequestTemplate template) {ServletRequestAttributes requestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();if (requestAttributes != null) {HttpServletRequest request = requestAttributes.getRequest();String access_token = request.getHeader("Authorization");log.info("从Request中解析出token:{}", access_token);//设置tokentemplate.header("Authorization",access_token);}}
}

3.2、JavaBean 配置拦截器

3.2.1、新建配置类

public class FeignInterceptorConfig {@Beanpublic TokenAuthRequestInterceptor tokenAuthRequestInterceptor() {return new TokenAuthRequestInterceptor();}
}

3.2.2、在 UserFeignService @FeignClient 注解 configuration 指定这个配置类

@FeignClient(value = "user-service", path = "/user", configuration = FeignInterceptorConfig.class)
public interface UserFeignService {@RequestMapping("/findUserNeedAuth/{id}")String findUserNeedAuth(@PathVariable("id") String id);
}

 3.3、OrderController 调用 UserFeignService

@RestController
@RequestMapping("/order")
public class OrderController {@Autowiredprivate UserFeignService userFeignService;@RequestMapping("/placeOrderNeedAuth/{userId}")public String placeOrderNeedAuth(@PathVariable String userId) {String username = userFeignService.findUserNeedAuth(userId);return "用户[" + username + "]下单成功!";}
}

3.4、UserController 校验 token

@RestController
@RequestMapping("/user")
public class UserController {@Value("${server.port}")private String port;@RequestMapping("/findUserNeedAuth/{id}")public String findUserNeedAuth(@PathVariable String id, @RequestHeader("Authorization") String token) {if (StringUtils.isBlank(token)) {throw new IllegalArgumentException("参数缺失!");}// 校验tokenif (!"feign123".equals(token)) {throw new  IllegalArgumentException("token错误!");}// 模拟从数据库获取用户Map<String, String> map = new HashMap<>();map.put("1", "小林:"+port);map.put("2", "小王:"+port);return map.get(id);}
}

这段代码只是进行模拟校验。 

  • 实际不可能在每个方法中进行 token 校验。
  • 校验失败抛出的异常也需要进行统一异常处理。

3.5、调用测试

GET http://localhost:8011/order/placeOrderNeedAuth/1
Accept: application/json
Authorization: feign123

Order 模块日志:

3.6、yml 配置拦截器

除了在 JavaBean 中配置拦截器外,还可以在 yml 中配置拦截器。

3.6.1、去掉 UserFeignService @FeignClient 注解 configuration 配置

3.6.2、在 order 模块 application.yml 配置

测试结果是一样的。

四、源码

http://www.xdnf.cn/news/185293.html

相关文章:

  • 基于javaweb的SpringBoot在线电子书小说阅读系统设计与实现(源码+文档+部署讲解)
  • Java详解LeetCode 热题 100(02):LeetCode 49. 字母异位词分组(Group Anagrams)详解
  • 一、接口测试01
  • 基于Python Flask的深度学习电影评论情感分析可视化系统(2.0升级版,附源码)
  • 简单的 shell 程序
  • 德州仪器(TI)—TDA4VM芯片详解—目录
  • 十七、系统可靠性分析与设计
  • Vue3 + OpenLayers 开发教程 (六)WebGL渲染优化
  • 【Nova UI】十二、打造组件库之按钮组件(上):迈向功能构建的关键一步
  • Linux系统类型及常用操作命令总结
  • Linux一个系统程序——进度条
  • QT中的事件及其属性
  • 大学之大:伦敦政治经济学院2025.4.27
  • onnexruntime u2net sharp 实现开源图片处理软件
  • vue 打包设置
  • DFPatternFunctor遍历计算图
  • 【博客系统】博客系统第一弹:博客系统项目配置、MyBatis-Plus 实现 Mapper 接口、处理项目公共模块:统一返回结果、统一异常处理
  • 关于华为高斯数据库出现Invalid or unsupported by client SCRAM mechanisms定位解决的过程
  • -信息革命-
  • OpenManus云端部署及经典案例应用
  • 心磁图技术突破传统局限!心血管疾病早筛迈入“三零“新时代
  • TV launcher官方下载-tv launcher汉化版-tv桌面启动器极简下载
  • c++17 对于临时对象作为右值的优化
  • MRI学习笔记-conjunction analysis
  • Linux——线程(2)线程互斥(锁)
  • 机器学习 | 基于回归模型的交通需求预测案例分析及代码示例
  • 日本IT|UIUX主要的工作都是哪些?及职业前景
  • 【每日随笔】文化属性 ② ( 高维度信息处理 | 强者思维形成 | 认知重构 | 资源捕获 | 进化路径 )
  • LangChain构建大模型应用之RAG
  • 使用ROS实现多机通讯