欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Feign远程调用丢失请求头问题

程序员文章站 2022-07-14 18:40:22
...

Feign远程调用丢失请求头问题

Feign远程调用丢失请求头问题

feign默认构造的template中header没有数据 

Feign远程调用丢失请求头问题

解决:

Feign远程调用丢失请求头问题 参考https://mp.csdn.net/console/editor/html/104254815

package com.java.gulimall.order.config;

import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * @author jl
 * Created on 2020/9/14
 */
@Configuration
public class GuliFeignConfig {

    @Bean("requestInterceptor")
    public RequestInterceptor requestInterceptor() {
        return 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);
                    }
                }
            }
        };
    }
}

如果是在异步方法中调用feign会出现HttpServletRequest request = requestAttributes.getRequest()为null的情况,需要先获取主线程的request,再设置到子线程

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

        // 由于开启了新的线程,不能获取当前线程的session,需要设置到子线程中
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        // 使用异步编排提高效率
        CompletableFuture<Void> getAddress = CompletableFuture.runAsync(() -> {
            // 设置子线程的request
            RequestContextHolder.setRequestAttributes(requestAttributes);
            // 收货地址
            List<MemberAddressVo> address = memberFeignService.getAddress(memberResponseVo.getId());
            orderConfirmVo.setAddressVos(address);
        }, executor);

        CompletableFuture<Void> currentUserCartItem = CompletableFuture.runAsync(() -> {
            // 设置子线程的request
            RequestContextHolder.setRequestAttributes(requestAttributes);
            // 获取当前用户的购物车商品项
            List<OrderItemVo> orderItemVos = cartFeignService.currentUserCartItem();
            orderConfirmVo.setItems(orderItemVos);
        }, executor);

        // 积分
        Integer integration = memberResponseVo.getIntegration();
        orderConfirmVo.setIntegration(integration);
        // 价格自动计算
        // 防重令牌

        CompletableFuture.allOf(getAddress,currentUserCartItem).get();
        return orderConfirmVo;