Feign远程调用丢失请求头问题
程序员文章站
2022-07-14 18:37:19
...
Feign远程调用丢失请求头问题
1.debug Feign远程
2.
3.远程调用实际是new
了一个新的RequestTemplate
,并没有把之前请求的header
给设置进去
4.
5.可以通过拦截器,拦截请求,然后在给请求设置上,原请求的header
信息即可
图解:
解决:
@Configuration
public class FeignConfig {
@Bean
public RequestInterceptor requestInterceptor(){
return new RequestInterceptor() {
@Override
public void apply(RequestTemplate requestTemplate) {
//1.RequestContextHolder拿到当前请求的数据,相当与拿到controller入参的HttpServletRequest
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//老请求
HttpServletRequest request = requestAttributes.getRequest();
//2.同步请求头信息->cookie
String cookie = request.getHeader("Cookie");
requestTemplate.header("Cookie",cookie);
}
};
}
}
Feign异步调用丢失请求头问题
还是上面的服务,只是改成异步调用
@Override
public OrderConfirmVo confirmOrder() {
OrderConfirmVo orderConfirmVo=new OrderConfirmVo();
//当前登录的用户
MemberResponseVo memberResponseVo = LoginUserInterceptor.loginUser.get();
//1.异步任务1 - 远程查询所有的收货地址列表
CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {
List<MemberAddressVo> address = memberFeignService.getAddress(memberResponseVo.getId());
orderConfirmVo.setMemberAddressVos(address);
}, threadPoolExecutor);
//2.异步任务2 - 远程查询购物车所有选中的购物项
CompletableFuture<Void> voidCompletableFuture1 = CompletableFuture.runAsync(() -> {
List<OrderItemVo> currentCartItems = cartFeignService.getCurrentCartItems();
orderConfirmVo.setItems(currentCartItems);
}, threadPoolExecutor);
//feign在远程调用之前要构造请求,调用很多的拦截器
try {
//等待所有任务完成
CompletableFuture.allOf(voidCompletableFuture,voidCompletableFuture1).get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
//3.查询用户积分
Integer integration = memberResponseVo.getIntegration();
orderConfirmVo.setIntegration(integration);
//4.其他数据自动计算
return orderConfirmVo;
}
改为了异步,发现之前的FeignConfig
配置类在获取ServletRequestAttributes
时,获取不到了
原因:旧请求是在线程A上,当使用异步时,是新开了一条线程去执行,新开的线程自然没有线程A的各种属性以及数据
图解:
解决:将旧线程中的属性RequestAttributes,设置到新线程中即可
@Override
public OrderConfirmVo confirmOrder() {
OrderConfirmVo orderConfirmVo=new OrderConfirmVo();
//当前登录的用户
MemberResponseVo memberResponseVo = LoginUserInterceptor.loginUser.get();
//解决:--------------------------------------
//获取旧线程的RequestAttributes
//RequestContextHolder底层使用的是ThreadLocal
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
//1.异步任务1 - 远程查询所有的收货地址列表
CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {
//解决:--------------------------------------
//将旧线程中的RequestAttributes,设置到线程中的RequestContextHolder里
RequestContextHolder.setRequestAttributes(requestAttributes);
List<MemberAddressVo> address = memberFeignService.getAddress(memberResponseVo.getId());
orderConfirmVo.setMemberAddressVos(address);
}, threadPoolExecutor);
//2.异步任务2 - 远程查询购物车所有选中的购物项
CompletableFuture<Void> voidCompletableFuture1 = CompletableFuture.runAsync(() -> {
//解决:--------------------------------------
//将旧线程中的RequestAttributes,设置到线程中的RequestContextHolder里
RequestContextHolder.setRequestAttributes(requestAttributes);
List<OrderItemVo> currentCartItems = cartFeignService.getCurrentCartItems();
orderConfirmVo.setItems(currentCartItems);
}, threadPoolExecutor);
//feign在远程调用之前要构造请求,调用很多的拦截器
try {
//等待所有任务完成
CompletableFuture.allOf(voidCompletableFuture,voidCompletableFuture1).get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
//3.查询用户积分
Integer integration = memberResponseVo.getIntegration();
orderConfirmVo.setIntegration(integration);
//4.其他数据自动计算
return orderConfirmVo;
}
配置类加个非空判断即可
@Configuration
public class FeignConfig {
@Bean
public RequestInterceptor requestInterceptor(){
return new RequestInterceptor() {
@Override
public void apply(RequestTemplate requestTemplate) {
//1.RequestContextHolder拿到当前请求的数据,相当与拿到controller入参的HttpServletRequest
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (requestAttributes!=null){
//老请求
HttpServletRequest request = requestAttributes.getRequest();
if (request!=null){
//2.同步请求头信息->cookie
String cookie = request.getHeader("Cookie");
requestTemplate.header("Cookie",cookie);
}
}
}
};
}
}
再次测试:
ok,解决
上一篇: H.264 打包 MPEG-TS 流
下一篇: 详解 H.264 NALU语法结构