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那里可以获取到服务携带过滤的请求头;

  • 相关阅读:
    20170411linux常用命令
    20170411oracle常用命令
    20170411-oracle 查询指定节点下的所有子节点包括直到叶子节点
    20170329oracle安装教程
    20170329plsql连接oracle
    20170329001怎么让plsql窗口列表保持
    Eclispse 换主题、皮肤、配色,换黑色主题护眼
    zbb20170303使用ssh一直找不到session,报错not found session in current thread
    zbb20170303_ant_build.xml详解
    hdu Farm Irrigation
  • 原文地址:https://www.cnblogs.com/coder-zyc/p/14811644.html
Copyright © 2011-2022 走看看