Feign远程调用丢失请求头的问题
feign调用过程和浏览器请求不一样,浏览器会自动携带请求头的信息,cookie,session等等,但是feign不会。
feign调用过程
首先,方法进入 invoke方法中
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (!"equals".equals(method.getName())) {
if ("hashCode".equals(method.getName())) {
return this.hashCode();
} else {
//执行方法通过方法名判断方法
return "toString".equals(method.getName()) ? this.toString() : ((MethodHandler)this.dispatch.get(method)).invoke(args);
}
} else {
try {
Object otherHandler = args.length > 0 && args[0] != null ? Proxy.getInvocationHandler(args[0]) : null;
return this.equals(otherHandler);
} catch (IllegalArgumentException var5) {
return false;
}
}
}
在执行发送请求之前,先封装request信息,这里的惹quest是feign新封装的
//在构建请求requtest
Request targetRequest(RequestTemplate template) {
//将项目中所有的拦截器遍历然后放到新的拦截器里,同步拦截器的信息
Iterator var2 = this.requestInterceptors.iterator();
while(var2.hasNext()) {
RequestInterceptor interceptor = (RequestInterceptor)var2.next();
interceptor.apply(template);
}
return this.target.apply(template);
}
解决办法:
这里需要自定义个一个拦截器,将老的请求信息同步到自己的请求中
@Bean
public RequestInterceptor requestInterceptor() {
return requestTemplate -> {
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
// 老的请求信息
HttpServletRequest request = requestAttributes.getRequest();
String cookie = request.getHeader("Cookie");
requestTemplate.header("Cookie", cookie);
};
}
这样feign调用的时候就能够携带老的请求信息了