0
点赞
收藏
分享

微信扫一扫

Feign远程调用丢失请求头问题以及异步丢失上下文问题解决方法


问题1描述

在微服务项目中,如果使用SpringSession能够解决session共享问题,是因为用户登录时会在浏览器保存一个Cookie值。

如果不通过浏览器,而是使用Feign调用另一个模块,这个Cookie就会丢失,造成在另一个模块拿不到用户登录的信息,如图:

Feign远程调用丢失请求头问题以及异步丢失上下文问题解决方法_cookie

解决方法

创建一个Feign的远程拦截器,实现RequestInterceptor

Feign远程调用丢失请求头问题以及异步丢失上下文问题解决方法_cookie_02

实现代码

@Configuration
public class MyFeignConfig {

@Bean("requestInterceptor")
public RequestInterceptor requestInterceptor() {

RequestInterceptor requestInterceptor = new RequestInterceptor() {
@Override
public void apply(RequestTemplate template) {
//1、使用RequestContextHolder拿到刚进来的请求数据
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (requestAttributes != null) {
//老请求
HttpServletRequest request = requestAttributes.getRequest();
if (request != null) {
//2、同步请求头的数据(主要是cookie)
//把老请求的cookie值放到新请求上来,进行一个同步
String cookie = request.getHeader("Cookie");
template.header("Cookie", cookie);
}
}
}
};
return requestInterceptor;
}
}

问题2描述

在使用ThreadLocal进行线程数据共享时,如果数据运行在同一线程,则可拿到数据,如果在使用线程池,进行多线程异步操作,则拿不到当前的Cookie,造成上下文件丢失的问题,如图:

Feign远程调用丢失请求头问题以及异步丢失上下文问题解决方法_session_03

解决方法:

在线程方法体外先获得RequestAttributes,然后在线程方法体内设置进去
代码:

public OrderConfirmVo confirmOrder() throws ExecutionException, InterruptedException {
OrderConfirmVo orderConfirmVo = new OrderConfirmVo();
MemberResponseVo memberResponseVo = LoginUserInterceptor.loginUser.get();

//获取当前线程请求头信息(解决Feign异步调用丢失请求头问题)
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
//1、远程查寻收货列表
CompletableFuture<Void> addressFuture = CompletableFuture.runAsync(() -> {
//在线程方法体内设置进去
RequestContextHolder.setRequestAttributes(requestAttributes);
List<MemberAddressVo> address = memberFeignService.getAddress(memberResponseVo.getId());
orderConfirmVo.setMemberAddressVos(address);
}, executor);

//2、查询购物信息
CompletableFuture<Void> cartItemsFuture = CompletableFuture.runAsync(() -> {
RequestContextHolder.setRequestAttributes(requestAttributes);
List<OrderItemVo> currentCartItems = cartFeignService.getCurrentCartItems();
orderConfirmVo.setItems(currentCartItems);
}, executor);

//合并运行
CompletableFuture.allOf(addressFuture, cartItemsFuture).get();


return orderConfirmVo;
}

QQ群:722865146
分布式商城下载:https://gitee.com/charlinchenlin/wysmall


举报

相关推荐

0 条评论