前言
feign的远程调用不会传递请求头,但是如果需要将接受的数据传递但远程调用的微服务接口那么该如何解决?
一、解决方案一
将请求头的信息获取后,直接在远程调用的方法上定义相关的形势参数将数据传递过去.
二、解决方案二:fegin的拦截器(实现RequestInterceptor接口)
1.ThreadLocal(同一个线程内数据共享,底层Map<Thread, Object>)
将数据存入到ThreadLocal中,代码如下(示例):
public class UserAuthThreadLocal {
private static final ThreadLocal<UserAuthInfo> threadLocal = new ThreadLocal();
/**
* 将对象设入ThreadLocal
* @param userAuthInfo
*/
public static void set(UserAuthInfo userAuthInfo) {
threadLocal.set(userAuthInfo);
}
/**
* 取出ThreadLocal中的UserAuthInfo对象
* @return
*/
public static UserAuthInfo get() {
return threadLocal.get();
}
}
然后通过fegin的监视器存入请求头中, 代码如下(示例):
public class OpenFeignRequestInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
//调用获取UserAuthLocal对象的方法
UserAuthInfo userAuthInfo = UserAuthThreadLocal.get();
template.header("userId", String.valueOf(userAuthInfo.getUserId()));
template.header("userTempId", userAuthInfo.getUserTempId());
}
}
其他微服务通过http请求直接获取请求头中的信息。
思考:每个想要获取请求头中数据的方法需要使用@RequestHeader
2.RequestContextHolder
RequestContextHolder可以在一个线程内共享HttpServletRequest对象,RequestContextHolder的底层原理是通过RequestContextListener进行实现
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest httpServletRequest = requestAttributes.getRequest();
String userId = httpServletRequest.getHeader("userId");
String userTempId = httpServletRequest.getHeader("userTempId");