OpenFeign实现携带请求头方案详细介绍
hi_kong 人气:0在使用OpenFeign请求其他服务接口时,默认不携带header信息,这样就导致无法携带登录用户信息。要解决这个问题,下面分两种情况进行处理。
1. 同步请求
对于同步请求,无需另作处理,只需从header中获取token信息,放入新请求即可。
@Configuration public class FeignConfig { @Bean public RequestInterceptor requestInterceptor(){ return new RequestInterceptor() { @Override public void apply(RequestTemplate requestTemplate) { ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); if(requestAttributes != null){ //获取请求的token信息 String token = requestAttributes.getRequest().getHeader(BaseConstant.TOKEN_HEADER); //同步到请求中 requestTemplate.header(BaseConstant.TOKEN_HEADER,token); return; } } }; } }
2. 异步请求
对于异步请求(例如A线程接到了HTTP请求,然后开启子线程B,B处理完成后调用openfeign接口),是无法使用上述方法的。因为RequestContextHolder.getRequestAttributes()方法获取的requestAttributesHolder变量,是ThreadLocal类型的:
private static final ThreadLocal<RequestAttributes> requestAttributesHolder = new NamedThreadLocal("Request attributes");
所以想到了一个简单的办法,在创建子线程时,将当前线程的token信息传递到子线程中。子线程在调用feign接口前,将token存入当前线程变量中,token类定义以及ThreadLocal定义如下:
//Token类定义 @Data public class TokenInfo implements Serializable { private String token; } //TokenContext类定义 public class TokenContext { public static final ThreadLocal<TokenInfo> tokenInfo = new ThreadLocal<>(); //设置token信息 public static void set(TokenInfo info){ tokenInfo.set(info); } //获取token信息 public static TokenInfo get(){ return tokenInfo.get(); } //移除token信息 public static void remove(){ tokenInfo.remove(); } }
调用接口处理:
TokenInfo info = new TokenInfo(); info.setToken(token); TokenContext.set(info); //调用接口 feign.interface; //一定要记得删除,不然后内存泄露风险 TokenContext.remove();
最后,上述创建的Bean改为:
@Configuration public class FeignConfig { @Bean public RequestInterceptor requestInterceptor(){ return new RequestInterceptor() { @Override public void apply(RequestTemplate requestTemplate) { //老请求 获取当前线程请求的请求信息 ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); if(requestAttributes != null){ String token = requestAttributes.getRequest().getHeader(BaseConstant.TOKEN_HEADER); //同步到请求中 requestTemplate.header(BaseConstant.TOKEN_HEADER,token); return; } TokenInfo tokenInfo = TokenContext.get(); if(userInfo != null){ String token = tokenInfo.getToken(); requestTemplate.header(BaseConstant.TOKEN_HEADER,BaseConstant.TOKEN_PREFIX + token); return; } } }; } }
加载全部内容