Feign远程调用丢失请求头问题
程序员文章站
2022-07-14 18:40:22
...
feign默认构造的template中header没有数据
解决:
参考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;