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

Posted lovoo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Feign远程调用丢失请求头问题以及异步丢失上下文问题解决方法相关的知识,希望对你有一定的参考价值。

问题1描述

在微服务项目中,如果使用SpringSession能够解决session共享问题,是因为用户登录时会在浏览器保存一个Cookie值。
如果不通过浏览器,而是使用Feign调用另一个模块,这个Cookie就会丢失,造成在另一个模块拿不到用户登录的信息,如图:
在这里插入图片描述

解决方法

创建一个Feign的远程拦截器,实现RequestInterceptor
在这里插入图片描述

实现代码

@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,造成上下文件丢失的问题,如图:
在这里插入图片描述

解决方法:

在线程方法体外先获得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

以上是关于Feign远程调用丢失请求头问题以及异步丢失上下文问题解决方法的主要内容,如果未能解决你的问题,请参考以下文章

openFeign远程调用丢失请求头

feign调用丢失请求头问题解决及原理分析

feign调用丢失请求头问题解决及原理分析

Feign请求头丢失解决方法

Feign请求头丢失解决方法

Feign请求头丢失解决方法