您的位置:首页 > 财经 > 金融 > 51免费版在线客服系统_龙岩市永定区疫情最新消息_同城推广_优化模型数学建模

51免费版在线客服系统_龙岩市永定区疫情最新消息_同城推广_优化模型数学建模

2025/1/12 23:22:22 来源:https://blog.csdn.net/shenxiaomo1688/article/details/144168692  浏览:    关键词:51免费版在线客服系统_龙岩市永定区疫情最新消息_同城推广_优化模型数学建模
51免费版在线客服系统_龙岩市永定区疫情最新消息_同城推广_优化模型数学建模

在使用Feign进行远程调用时,当前服务是能拿到请求头信息的,请求头包含有登录认证Cookie等重要信息,但是在调用远程服务时,远程服务却拿不到请求头信息,因为使用Feign进行远程调用实际上是发起新的Request请求了,所以就获取不到上一个请求的数据。请求示意图如下所示:

此时我们需要在在当前服务中添加配置类,用于将当前请求信息传递给远程服务,下面是配置类示例代码:

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: * @Desc:* @create:**/
@Configuration
public class GuliFeignConfig {@Bean("requestInterceptor")public RequestInterceptor requestInterceptor(){return new RequestInterceptor() {@Overridepublic void apply(RequestTemplate template) {//RequestContextHolder是feign设计用于获取请求上下文数据的工具类ServletRequestAttributes requestAttributes= (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = requestAttributes.getRequest();if(request!=null){//获取源请求的请求头数据String cookie = request.getHeader("Cookie");//给新请求同步源请求的Cookietemplate.header("Cookie",cookie);}}};}
}

 添加上面的配置类后,在同步环境中能可确保远程服务能获取当前服务的请求头数据。但是如果使用异步操作,仅靠上面的配置类是不够的。这是因为:

数据是线程私有的,不能共享,所以使用异步的远程服务获取不了主线程的请求数据。此时需要进行配置:

方法1:硬编码,在主线程中获取到请求数据,在异步线程操作中赋值进去,

优点:简单易懂,上手快;

缺点:侵入业务代码,且每使用一个线程就要写这样一段代码,还会导致大量冗余代码。

示例代码:

         //获取当前线程请求数据RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();//使用异步编排处理多个远程请求任务//1.远程查询会员的收货地址CompletableFuture<Void> getAddressFuture = CompletableFuture.runAsync(() -> {//使用异步编排后,由于线程不同,需要将源请求上下文数据赋给当前线程RequestContextHolder.setRequestAttributes(requestAttributes);List<MemberAddressVo> address = orderFeignServie.getAddress(memberRespVo.getId());orderConfirmVo.setAddress(address);}, executor);//2.远程查询购物车中的购物项CompletableFuture<Void> getCartItemFuture = CompletableFuture.runAsync(() -> {//使用异步编排后,由于线程不同,需要将请求源上下文数据赋给当前线程RequestContextHolder.setRequestAttributes(requestAttributes);List<OrderItemVo> orderItemVos = cartFeignService.currentUserCartItem();orderConfirmVo.setItems(orderItemVos);}, executor);

方法2: 创建一个抽象类,实现Runnable方法。

优点:无侵入,代码简洁;

下面是示例代码:

public abstract class MyRunnable implements Runnable{private RequestAttributes requestAttributes;public MyRunnable() {requestAttributes = RequestContextHolder.getRequestAttributes();}public abstract void myRun();@Overridepublic void run() {//每一个线程都来共享之前的请求数据RequestContextHolder.setRequestAttributes(requestAttributes);myRun();}
}

然后在业务代码中使用MyRunnable的myRun()方法:

//开启第一个异步任务
CompletableFuture<Void> addressFuture2 = CompletableFuture.runAsync(new MyRunnable() {@Overridepublic void myRun() {//1、远程查询所有的收获地址列表List<MemberAddressVo> address = memberFeignService.getAddress(memberResponseVo.getId());confirmVo.setMemberAddressVos(address);}
}, threadPoolExecutor);

 如此便可在异步使用Feign进行远程调用时获取到当前请求的请求数据。

更多信息可参考:谷粒商城实战笔记-问题记录-Feign异步调用丢失请求头问题_异步调用feign请求对象丢失-CSDN博客

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com