zoukankan      html  css  js  c++  java
  • 关于feign调用请求头丢失分析

    feign是Spring Cloud提供的伪http客户端(本质还是用http),封装了Http调用流程,使用Java接口注解的方式无感知调用Http请求,不用像Ribbon中通过封装HTTP请求报文的方式调用,feign默认集成了Ribbon;

    A服务通过feign接口调用B服务,A中带有请求头,但是请求到了服务B,请求头丢失了,如下图

    当请求到了服务B的拦截器,获取请求头,此时请求头获取不到,如下图

    原因如下:

    当服务A调用feign接口的时候,调用服务B的请求是新创建的,跟服务A原有的请求不是不同一个,因此新创建的请求不能拿到之前的请求的所携带的参数;

    feign.SynchronousMethodHandler#invoke

    RequestTemplate的对象是新创建的;

    创建后的RequestTemplate对象中的headers为空的;

    之后执行到executeAndDecode方法,如下

    feign.SynchronousMethodHandler#executeAndDecode

    targetRequest方法里面是对请求进行拦截,下面的client.execute是执行Http请求;

    feign.SynchronousMethodHandler#targetRequest.

    RequestInterceptor是feign的请求拦截器,因此可以在这里做处理;

     RequestInterceptor的继承树如下:

    根据现有的实现,仿写如下:

    private static final String ACCESSTOKEN_HEADER = "accessToken";
    
    @Bean
    public RequestInterceptor requestInterceptor() {
    	return template -> {
    		ServletRequestAttributes attributes =
    				(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    
    		if (attributes != null) {
    			HttpServletRequest request = attributes.getRequest();
    			log.info(request.getHeaderNames().toString());
    			template.header(ACCESSTOKEN_HEADER, request.getHeader(ACCESSTOKEN_HEADER));
    		} else {
    			log.warn("requestInterceptor获取Header空指针异常");
    		}
    	};
    }
    

      

    之后在服务B那里可以获取到服务携带过滤的请求头;

  • 相关阅读:
    组合
    面向对象初识, 类名,对象的的使用, 类名称空间和对象名称空间
    内置函数2 递归函数
    内置函数~~~
    生成器 列表推导式 列表表达式
    函数名应用 闭包 迭代器
    函数 动态参数, 名称空间 作用域 取值顺序,函数的嵌套
    函数初识~~
    文件操作要点
    Mysql索引原理
  • 原文地址:https://www.cnblogs.com/coder-zyc/p/14811644.html
Copyright © 2011-2022 走看看