feign调用自动转发请求头header


那么如何解决请求头的传递问题呢?

一 最容易想到的方法是在转发和请求时主动将header参数传入。

通过在controller中设置RequestHeader参数。这种方法的弊端是每次都得修改controller中的api方法,耦合性高,一旦需要增加header参数,则所有涉及到的controller方法都要调整一遍。

二 比较通用的方法是使用拦截器,在转发请求时,统一添加header信息。

@Component
public class FeignClientsConfigurationCustom implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate requestTemplate) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes();
        if (null != attributes) {
            HttpServletRequest request = attributes.getRequest();
            if (null != request) {
                Enumeration<String> headerNames = request.getHeaderNames();
                if (headerNames != null) {
                    while (headerNames.hasMoreElements()) {
                        String name = headerNames.nextElement();
                        String values = request.getHeader(name);
                        requestTemplate.header(name, values);
                    }
                }
            }
        }
    }
}

但是,如果开启了hystrix隔离策略,则会影响header参数的转发。

hystrix的默认隔离策略是线程隔离。

在这种情况下,转发调用和真正请求的不是同一个线程,因此没有办法获取到ThreadLocal中的数据。

此时,ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();  拿到的attributes是null,因为这里用到了ThreadLocal。

因此在线程隔离策略下,服务端拿不到header信息。那么怎么办呢?

解决方案一:修改默认隔离策略为信号量模式

hystrix.command.default.execution.isolation.strategy=SEMAPHORE,这样的话转发线程和请求线程实际上是一个线程。但是这种方法有些弊端,hystrix官方不建议使用信号量模式。

解决方案二:自定义hystrix隔离策略

思路是将现有的并发策略作为新并发策略的成员变量。在新并发策略中,返回现有并发策略的线程池、Queue,将策略加到Spring容器即可。目前,Spring Cloud Sleuth以及Spring Security都通过该方式传递 ThreadLocal 对象。

 

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM