问题描述
在微服务项目中,通过Feign远程调用另一个模块的接口,由于请求头没传过去导致接口调用失败
解决办法
feign调用远程接口时,会扫描所有的拦截器,执行apply方法,
我们可以创建一个拦截器放到spring容器中,
在拦截器里把原来的头都放到新创建的请求里
代码实现
// 将Feign拦截器注入为 Bean
@Configuration
public class FeginAutoConfiguration {
@Bean
public MyFeignInterceptor myFeignInterceptor() {
return new MyFeignInterceptor();
}
}
/**
* Feign拦截器
*/
@Slf4j
public class MyFeignInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
log.warn("Feign拦截器生效了---->");
// 此种方式是线程安全的
ServletRequestAttributes attributes =
(ServletRequestAttributes) RequestContextHolder
.getRequestAttributes();
// 不为空时取出请求中的header 原封不动的设置到feign请求中
if (null != attributes) {
HttpServletRequest request = attributes.getRequest();
if (null != request) {
// 遍历设置 也可从request取出整个Header 写到RequestTemplate 中
Enumeration<String> headerNames = request.getHeaderNames();
if (headerNames != null) {
while (headerNames.hasMoreElements()) {
String name = headerNames.nextElement();
String values = request.getHeader(name);
if("authorization".equals(name)) {
log.error("---> {}:{}", name, values);
//增加请求头 authorization
template.header(name, values);
}
}
}
}
}
}
}