请求丢失原因是因为feign调用会使用新的模板发送请求
于是会丢失老请求的数据
解决方法:
package com.xdtmall.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;
@Configuration
public class XdtFeignConfig {
@Bean("requestInterceptor")
public RequestInterceptor requestInterceptor() {
return new RequestInterceptor() {
@Override
public void apply(RequestTemplate template) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();//拿到当前的所有请求属性
HttpServletRequest request = attributes.getRequest();//获取到当前请求
if (request != null) {
//同步请求头数据,cookie
String cookie = request.getHeader("Cookie");
//给新请求同步老请求的cookie
template.header("Cookie", cookie);
System.out.println("我进入了远程feign");
}
}
};
}
}
在异步的情况下也会出现feign请求丢失的问题。原因是feign底层用的是ThreadLock线程共享数据。当异步调用时线程号不一样,所以异步调用也会丢失信息。解决方法:
每一个异步任务都重新设置一下请求属性
//远程查询所有的收获地址列表
MemberRespVo memberRespVo = LoginUserInterceptor.loginUser.get();//拿到当前用户session里的数据
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
CompletableFuture<Void> getAddress = CompletableFuture.runAsync(() -> {
RequestContextHolder.setRequestAttributes(requestAttributes);
List<MemberAddressVo> address = memberFeignService.getAddress(memberRespVo.getId());
confirmVo.setAddress(address);
}, executor);
//远程查询购物车所有选中的购物项
CompletableFuture<Void> cartFuture = CompletableFuture.runAsync(() -> {
List<OrderItemVo> items = cartFeignService.currentUserCartItems();
RequestContextHolder.setRequestAttributes(requestAttributes);
confirmVo.setItems(items);
}, executor);