SpringCloudFeign自定义配置(重试、拦截与错误码处理)-openFeign实现全链路JWT令牌信息不丢失-《Java笔记》

admin 2025-10-19 05:54:58 编程 来源:ZONE.CI 全球网 0 阅读模式

Java SpringCloud

什么是令牌中继?

令牌中继通俗的讲则是让令牌在微服务链路调用中传递下去,保证各个微服务能够获取令牌中的用户信息。以下订单的例子来说,如下图:下单流程客户端携带令牌请求网关,网关鉴权成功后会将令牌中的用户信息解析出来放在请求头中下发给订单服务,同样的,订单服务需要将用户信息传递给账户服务获取该用户的账户信息。那么问题来了?如何保证网关服务->订单服务->账户服务这条链路中的用户信息传递下去是个痛点

解决方案

令牌在openFeign调用过程中是不能自动中继的,因此必须手动的将令牌信息传递下去。注意:openFeign在开启熔断降级后内部调用开启了子线程,因此传统的方案直接在RequestInterceptor中设置是不可行的。那么如何保证子线程也能获取请求头中的用户信息呢?答案是:RequestContextHolder这个神器。RequestContextHolder内部通过InheritableThreadLocal实现子线程共享信息。在FeignCircuitBreakerInvocationHandler这个类中也是有如下一行代码:

  1. RequestContextHolder.setRequestAttributes(requestAttributes);

正是使用RequestContextHolder将request的信息保存在其中,因此实现令牌中继只需要读取RequestContextHolder的信息即可。详细代码如下:

  1. @Component
  2. public class FeignRequestInterceptor implements RequestInterceptor {
  3. @Override
  4. public void apply(RequestTemplate template) {
  5. //从RequestContextHolder中获取HttpServletRequest
  6. HttpServletRequest httpServletRequest = RequestContextUtils.getRequest();
  7. //获取RequestContextHolder中的信息
  8. Map<String, String> headers = getHeaders(httpServletRequest);
  9. //放入feign的RequestTemplate中
  10. for (Map.Entry<String, String> entry : headers.entrySet()) {
  11. template.header(entry.getKey(), entry.getValue());
  12. }
  13. }
  14. /**
  15. * 获取原请求头
  16. */
  17. private Map<String, String> getHeaders(HttpServletRequest request) {
  18. Map<String, String> map = new LinkedHashMap<>();
  19. Enumeration<String> enumeration = request.getHeaderNames();
  20. if (enumeration != null) {
  21. while (enumeration.hasMoreElements()) {
  22. String key = enumeration.nextElement();
  23. String value = request.getHeader(key);
  24. map.put(key, value);
  25. }
  26. }
  27. return map;
  28. }
  29. }
以太坊cppgolang区别 编程

以太坊cppgolang区别

以太坊是一种去中心化的开源平台,它采用智能合约技术,旨在构建和运行不受干扰的分布式应用程序。作为目前最受欢迎的区块链平台之一,以太坊提供了多种编程语言的支持,其
progolang 编程

progolang

Go语言(Golang)是由Google开发的一门静态类型编程语言。作为一名专业的Golang开发者,我深知这门语言的优势和特点。在本文中,我将介绍Golang
golangn个发送者 编程

golangn个发送者

Golang是一种开源的编程语言,由Google团队开发,旨在提高程序的并发性和简化软件开发过程。在Go语言中,有时需要向多个接收者发送信息。本文将介绍如何在G
golang技能图谱 编程

golang技能图谱

从互联网行业的快速发展到人工智能技术的日益成熟,各种编程语言也应运而生。而在这众多的编程语言中,Golang(即Go)作为一门强大且高效的开发语言备受关注。Go
评论:0   参与:  8