默认spring-boot 微服务中 用feign来做服务间调用,是不会携带token传递的。为了能让服务间调用的时候带上token,需要进行配置,增强resTemplate
 

1、先实现请求拦截器

/**
* feign配置token
*/
@Configuration
public class FeignRequestInterceptor implements RequestInterceptor { @Override
public void apply(RequestTemplate requestTemplate) {
// 这里可以添加feign请求的全局参数
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attributes == null || attributes.getRequest() == null) {
return;
}
HttpServletRequest request = attributes.getRequest();
requestTemplate.header("token", request.getHeader("token"));
requestTemplate.header("feignClient", "ifaas-hotel-robot-platform"); }
}
 

2.在@FeignClient接口里添加configuration = {FeignConfig.class}

@FeignClient(name="被调用的服务名", configuration={FeignRequestInterceptor .class})
由于feign的熔断器hystrix的隔离策略的原因,feign调用线程和主线程隔离了,请求上下文不共用,导致feign拦截器中 RequestContextHolder.getRequestAttributes()为空
 
原因:
此属性指示HystrixCommand.run()执行哪种隔离策略,是以下两种选择之一:
  • THREAD —它在单独的线程上执行,并发请求受线程池中线程数的限制
  • SEMAPHORE —它在调用线程上执行,并发请求受信号量限制
 

3、解决feign中RequestContextHolder.getRequestAttributes()为null方案有两种:

3.1、修改隔离策略:默认是 采用THREAD ,修改成SEMAPHORE 即可,但是不推荐这种做法,因为并发请求收到限制。

 

3.2、自定义feign的并发策略 继承HystrixConcurrencyStrategy,然后重写wrapCallable方法。如下:

import com.netflix.hystrix.strategy.HystrixPlugins;
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder; import java.util.concurrent.Callable; /**
* Created by YangGuanRong
* date: 2022/3/8
*/
@Slf4j
@Primary
@Component
public class CustomFeignHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy { public CustomFeignHystrixConcurrencyStrategy() {
try { HystrixPlugins.getInstance().registerConcurrencyStrategy(this); } catch (Exception e) {
log.error("Failed to register Sleuth Hystrix Concurrency Strategy", e);
}
} @Override
public <T> Callable<T> wrapCallable(Callable<T> callable) {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
return new WrappedCallable<>(callable, requestAttributes);
} static class WrappedCallable<T> implements Callable<T> {
private final Callable<T> target;
private final RequestAttributes requestAttributes; public WrappedCallable(Callable<T> target, RequestAttributes requestAttributes) {
this.target = target;
this.requestAttributes = requestAttributes;
} /**
* feign opens the fuse (hystrix): feign.hystrix.enabled=ture, and uses the default signal isolation level,
* The HttpServletRequest object is independent of each other in the parent thread and the child thread and is not shared.
* So the HttpServletRequest data of the parent thread used in the child thread is null,
* naturally it is impossible to obtain the token information of the request header In a multithreaded environment, call before the request, set the context before the call
*
* feign启用了hystrix,并且feign.hystrix.enabled=ture。采用了线程隔离策略。
* HttpServletRequest 请求在对象在父线程和子线程中相互独立,且不共享
* 所以父线程的 HttpServletRequest 在子线程中为空,
* 所以通常 在多线程环境中,在请求调用之前设置上下文
* @return T
* @throws Exception Exception
*/
@Override
public T call() throws Exception {
try {
// Set true to share the parent thread's HttpServletRequest object setting
RequestContextHolder.setRequestAttributes(requestAttributes, true);
return target.call();
} finally {
RequestContextHolder.resetRequestAttributes();
}
}
}
}

feign服务中调用,传递token的更多相关文章

  1. SpringCloud初体验:三、Feign 服务间调用(FeignClient)、负载均衡(Ribbon)、容错/降级处理(Hystrix)

    FeignOpenFeign Feign是一种声明式.模板化的HTTP客户端. 看了解释过后,可以理解为他是一种 客户端 配置实现的策略,它实现 服务间调用(FeignClient).负载均衡(Rib ...

  2. Spring Cloud Feign 服务消费调用(三)

    序言 Spring Cloud Netflix的微服务都是以HTTP接口的形式暴露的,所以可以用Apache的HttpClient或Spring的RestTemplate去调用 而Feign是一个使用 ...

  3. 在Delphi开发的服务中调用指定应用程序

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://fxh7622.blog.51cto.com/63841/529033 在很多时候 ...

  4. Spring Cloud OAuth2.0 微服务中配置 Jwt Token 签名/验证

    关于 Jwt Token 的签名与安全性前面已经做了几篇介绍,在 IdentityServer4 中定义了 Jwt Token 与 Reference Token 两种验证方式(https://www ...

  5. 代码书写C++ 中调用传递与指针传递根本区别

    从概念上讲.指针从本质上讲就是存放变量地址的一个变量,在逻辑上是独立的,它可以被改变,包括其所指向的地址的改变和其指向的地址中所存放的数据的改变.而引用是一个别名,它在逻辑上不是独立的,它的存在具有依 ...

  6. 【多线程】java多线程Completablefuture 详解【在spring cloud微服务之间调用,防止接口超时的应用】【未完成】

    参考地址:https://www.jianshu.com/p/6f3ee90ab7d3 示例: public static void main(String[] args) throws Interr ...

  7. DELPHI编写服务程序总结(在系统服务和桌面程序之间共享内存,在服务中使用COM组件)

    DELPHI编写服务程序总结 一.服务程序和桌面程序的区别 Windows 2000/XP/2003等支持一种叫做“系统服务程序”的进程,系统服务和桌面程序的区别是:系统服务不用登陆系统即可运行:系统 ...

  8. Spring Cloud中Feign如何统一设置验证token

    代码地址:https://github.com/hbbliyong/springcloud.git 原理是通过每个微服务请求之前都从认证服务获取认证之后的token,然后将token放入到请求头中带过 ...

  9. SpringCloud系列——Feign 服务调用

    前言 前面我们已经实现了服务的注册与发现(请戳:SpringCloud系列——Eureka 服务注册与发现),并且在注册中心注册了一个服务myspringboot,本文记录多个服务之间使用Feign调 ...

随机推荐

  1. springcloud 实现简单的 消费者和生产者 模式(Restfule 的风格)

    一.springcloud 实现简单的 消费者和生产者 模式(Restfule 的风格) 1.实现简单的消费者和生产者 springcloud使用的http协议进行传输数据,也就是说springclo ...

  2. from 表单上传多个文件?

    和单个上传文件基本相同,就是需要在后台控制器中,用数组来接收 jsp页面提交过来的file数据. 也分为三个部分演示. 一.jsp <%-- Created by IntelliJ IDEA. ...

  3. oracle中的常用函数、字符串函数、数值类型函数、日期函数,聚合函数。

    一.字符串的常用函数. --一.oracle 字符串常用函数 --1. concat 连接字符串的函数,只能连接[两个]字符串. 字符写在括号中,并用逗号隔开! --2."||"符 ...

  4. CF1399F Yet Another Segments Subset

    首先注意一下题面要求,使得选出的线段两两要么包含要么不相交,也就是说一条线段可能会出现不相交的几条线段,而这些线段上面也可能继续这样包含线段.然后我们可以发现我们要做的实际上是在这条线段上选取几条线段 ...

  5. jvm与dvm两种虚拟机的不同

    jvm : java虚拟机 sun dvm:  dalvik虚拟机  google     区别:         1.基于的架构不同,jvm 基于栈架构,栈是位于内存上的一个空间,执行指令操作,需要 ...

  6. 版本控制SVN

    为什么需要版本控制软件 代码的冻结 避免在重大的考核之前改动代码 每个稳定版本都在服务器保存进度,随时可以回退 需求频繁的变化不要改动稳定的代码,不要改别人写好的代码 为什么需求会变化?有时候产品自己 ...

  7. CocoaPods使用专题 by h.l

    cocoaPods安装 CocoaPods安装和使用教程(code4app) cocoapods使用问题解决 cocoapods慢如何解决? CocoaPods停在Analyzing dependen ...

  8. getter/setter方法

    1.setter方法 作用:用来设置成员变量,可以在方法里面过滤掉一些不合理的值 命名规范: 必须是对象方法 返回值类型为void 方法名必须以set开头,而且后面跟上成员变量名去掉"_&q ...

  9. @play.data.binding.NoBinding

    新的@play.data.binding.NoBinding注解允许我们定义一些"不应该被绑定"的字段,以防出现安全问题.例如: public class User extends ...

  10. JS快速入门(二)

    目录 JS快速入门(二) 结构图 BOM window对象 open() window子对象 location对象 history对象(了解) navigator 对象 screen对象 BOM 定时 ...