Feign在远程调用之前要构造请求,会调用很多拦截器来对请求进行增强,如果没有的拦截器,会创建一个新的request请求,这个请求里什么都没有
解决:添加拦截器解决远程调用丢失请求头
package cn.cloud.xmall.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.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
/**
* @Description: Feign拦截器
* @author: Freedom
* @QQ: 1556507698
* @date:2022/4/9 13:30
*/
@Configuration
public class XmallFeignConfig {
@Bean
public RequestInterceptor requestInterceptor() {
return template -> {
//使用RequestContextHolder拿到Controller刚进来的请求数据,ServletRequestAttributes 父类实现了 RequestAttributes
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = requestAttributes.getRequest(); //老请求
//同步请求头信息 cookie
String cookie = request.getHeader("Cookie"); //拿到老请求的cookie
//给新请求同步老请求cookie
template.header("Cookie",cookie ); //cookie放到新请求理
};
}
;
}
解决:异步情况丢失请求上下文
在自己的线程下再来共享requestAttributes就可以解决
//开启异步任务
CompletableFuture<Void> getAddress = CompletableFuture.runAsync(() -> {
//1.远程查询所有的收货地址列表
RequestContextHolder.setRequestAttributes(requestAttributes);
List<MemberAddressVo> address = memberFeignService.getAddress(memberRespVo.getId());
confirmVo.setAddress(address);
}, executor);
错误记录:java.lang.IllegalStateException:Duplicate key
原因
Map中出现了和被转换的List中重复的key记录
try {
//发起远程请求
R skuHasStock = wareFeignService.getSkusHasStock(skuIds);
//转换为map
TypeReference<List<SkuHasStockVo>> typeReference = new TypeReference<List<SkuHasStockVo>>() {};
stockMap = skuHasStock.getData(typeReference).stream()
.collect(
Collectors.toMap(
SkuHasStockVo::getSkuId,
item -> item.getHasStock(),
(v1,v2)->v1)
);
}catch (Exception e){
log.error("库存服务查询异常:原因{}",e);
}
解决方案
两个key 相同时,保留先存进去的那个元素
Collectors.toMap(
SkuHasStockVo::getSkuId,
item -> item.getHasStock(),
(v1,v2)->v1)
);