RequestContextHolder多线程获取不到request对象
RequestContextHolder多线程获取不到request对象,调用feign接口时,在Feign中的RequestInterceptor也获取不到HttpServletRequest问题解决方案。
1.RequestContextHolder多线程获取不到request对象
异常信息,报错如下:
2024-07-09 22:06:32.320 [pool-5-thread-2] ERROR com.mergeplus.handler.ObjectHandler:227 - class: interface org.jeecg.common.system.api.client.SysFeignClient, methodName=mergeRegion, error: {}
java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131)at org.springframework.web.context.support.WebApplicationContextUtils.currentRequestAttributes(WebApplicationContextUtils.java:313)at org.springframework.web.context.support.WebApplicationContextUtils$RequestObjectFactory.getObject(WebApplicationContextUtils.java:329)at org.springframework.web.context.support.WebApplicationContextUtils$RequestObjectFactory.getObject(WebApplicationContextUtils.java:324)at org.springframework.beans.factory.support.AutowireUtils$ObjectFactoryDelegatingInvocationHandler.invoke(AutowireUtils.java:283)at jdk.proxy2/jdk.proxy2.$Proxy179.getHeaderNames(Unknown Source)at com.mergeplus.handler.ObjectHandler.lambda$doHandler$0(ObjectHandler.java:155)at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run$$$capture(CompletableFuture.java:1768)at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java)at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)at java.base/java.lang.Thread.run(Thread.java:833)
异常错误截图:

2.解决方案
// 设置子线程共享(重点)final RequestAttributes attributes = RequestContextHolder.getRequestAttributes();merges.stream().map(e -> CompletableFuture.supplyAsync(() -> {JSONObject returnMap = null;try {if (e.getClientBean() != null) {// 设置当前线程的 RequestAttributes(重点)RequestContextHolder.setRequestAttributes(attributes);Object returnValue = e.getMethod().invoke(e.getClientBean(), jsonObject.get(e.getSourceKey()));if (returnValue == null) {return e;}returnMap = JSON.parseObject(JSON.toJSONString(returnValue));if (returnMap == null || returnMap.isEmpty()) {return e;}result.put(e.getTargetKey(), returnMap.get(jsonObject.get(e.getSourceKey())));} else {if (e.getUrl() == null || e.getUrl().trim().length() == 0) {return e;}//设置Http的HeaderHttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_JSON);//设置访问参数HashMap<String, Object> params = new HashMap<>();if (e.getKey() == null || e.getKey().trim().length() == 0) {params.put(e.getSourceKey(), jsonObject.get(e.getSourceKey()));}//设置访问的EntityHttpEntity entity = new HttpEntity<>(params, headers);// todoResponseEntity<Object> exchange = restTemplate.exchange(e.getUrl(), HttpMethod.GET, entity, Object.class);if (exchange == null) {return e;}Object body = exchange.getBody();if (body == null) {return e;}returnMap = JSON.parseObject(JSON.toJSONString(body));if (returnMap == null || returnMap.isEmpty()) {return e;}result.put(e.getTargetKey(), returnMap.get(jsonObject.get(e.getSourceKey())));// if (body instanceof Map) {
// returnMap = (Map) body;
// if (returnMap == null || returnMap.isEmpty()) {
// return e;
// }
// result.put(e.getTargetKey(), returnMap.get(jsonObject.get(e.getSourceKey())));
// }}} catch (Exception ex) {log.error("class: {}, methodName={}, error: {}", e.getClientBeanClazz(), e.getMethod().getName(), ex);} finally {RequestContextHolder.resetRequestAttributes(); // 记得在最后重置请求属性(重点)}return e;}, executor)).toList().stream().map(CompletableFuture::join).collect(Collectors.toList());


FeignInterceptorConfig代码
package org.jeecg.config;import java.io.IOException;
import java.util.*;import feign.RequestTemplate;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.config.mqtoken.UserTokenContext;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.PathMatcherUtil;
import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.common.util.TokenUtils;
import org.jeecg.config.sign.interceptor.SignAuthConfiguration;
import org.jeecg.config.sign.util.HttpUtils;
import org.jeecg.config.sign.util.SignUtil;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.FeignAutoConfiguration;
import org.springframework.cloud.openfeign.support.SpringDecoder;
import org.springframework.cloud.openfeign.support.SpringEncoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;
import org.springframework.http.MediaType;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;import feign.Feign;
import feign.Logger;
import feign.RequestInterceptor;
import feign.codec.Decoder;
import feign.codec.Encoder;
import feign.form.spring.SpringFormEncoder;
import lombok.extern.slf4j.Slf4j;/*** @Description: FeignConfig* @author: JeecgBoot*/
@ConditionalOnClass(Feign.class)
@AutoConfigureBefore(FeignAutoConfiguration.class)
@Slf4j
@Configuration
public class FeignInterceptorConfig {@Beanpublic RequestInterceptor requestInterceptor() {return requestTemplate -> {ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();if (requestAttributes == null) {return;}//1.获取请求对象HttpServletRequest request = requestAttributes.getRequest();Enumeration<String> headerNames = request.getHeaderNames();if (headerNames == null || !headerNames.hasMoreElements()) {return;}//2.获取请求对象中的所有的头信息(网关传递过来的)while (headerNames.hasMoreElements()) {String name = headerNames.nextElement();//头的名称// 跳过content-length,不然可能会报too many bites written问题if ("content-length".equalsIgnoreCase(name)) {continue;}String value = request.getHeader(name);//头名称对应的值// System.out.println("name:" + name + "::::::::value:" + value);//3.将头信息传递给feign (restTemplate)requestTemplate.header(name,value);// if (CommonConstant.X_ACCESS_TOKEN.equals(name) && StringUtils.isBlank(value)) {
// String token = UserTokenContext.getToken();
// requestTemplate.header(CommonConstant.X_ACCESS_TOKEN, token);
// }}//================================================================================================================//针对特殊接口,进行加签验证 ——根据URL地址过滤请求 【字典表参数签名验证】// todoif (PathMatcherUtil.matches(Arrays.asList(PathMatcherUtil.SIGN_URL_LIST),requestTemplate.path())) {
// if (PathMatcherUtil.matches(Arrays.asList(SignAuthConfiguration.SIGN_URL_LIST),requestTemplate.path())) {try {log.info("============================ [begin] fegin api url ============================");log.info(requestTemplate.path());log.info(requestTemplate.method());String queryLine = requestTemplate.queryLine();String questionMark="?";if(queryLine!=null && queryLine.startsWith(questionMark)){queryLine = queryLine.substring(1);}log.info(queryLine);if(requestTemplate.body()!=null){log.info(new String(requestTemplate.body()));}SortedMap<String, String> allParams = HttpUtils.getAllParams(requestTemplate.path(),queryLine,requestTemplate.body(),requestTemplate.method());String sign = SignUtil.getParamsSign(allParams);log.info(" Feign request params sign: {}",sign);log.info("============================ [end] fegin api url ============================");requestTemplate.header(CommonConstant.X_SIGN, sign);requestTemplate.header(CommonConstant.X_TIMESTAMP, String.valueOf(System.currentTimeMillis()));} catch (IOException e) {e.printStackTrace();}}//================================================================================================================};}}
3.相关大数据学习demo地址:
https://github.com/carteryh/big-data
相关文章:
RequestContextHolder多线程获取不到request对象
RequestContextHolder多线程获取不到request对象,调用feign接口时,在Feign中的RequestInterceptor也获取不到HttpServletRequest问题解决方案。 1.RequestContextHolder多线程获取不到request对象 异常信息,报错如下: 2024-07-0…...
打造高效工作与生活质量的完美平衡
在快节奏的编程行业中,保持健康的工作与生活平衡是至关重要的。长时间坐在电脑前、面对紧凑的项目截止日期和频繁的加班文化,很容易导致身心健康问题,如眼睛疲劳、颈部和背部疼痛、压力累积、睡眠障碍乃至慢性疾病。因此,采取积极…...
【零基础】学JS之APIS第四天
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 非常期待和您一起在这个小…...
走进linux
1、为什么要使用linux 稳定性和可靠性: Linux内核以其稳定性而闻名,能够持续运行数月甚至数年而不需要重新启动。这对于服务器来说至关重要,因为它们需要保持长时间的稳定运行,以提供持续的服务 安全性: Linux系统…...
智能家居开发新进展:乐鑫 ESP-ZeroCode 与亚马逊 ACK for Matter 实现集成
日前,乐鑫 ESP-ZeroCode 与亚马逊 Alexa Connect Kit (ACK) for Matter 实现了集成。这对智能家居设备制造商来说是一项重大进展。开发人员无需编写固件或开发移动应用程序,即可轻松设计符合 Matter 标准的产品。不仅如此,开发者还可以在短短…...
本地事务和分布式事务
一、本地事务 1、事务的基本特性 数据库事务的几个基本特性:原子性、一致性、隔离性、持久性。 原子性:一系列的操作整体不可拆分,要么同时成功,要么同时失败。 一致性:数据在事务的前后,业务整体一…...
昇思25天学习打卡营第14天|基于MindNLP的文本解码原理
基于MindNLP的文本解码原理 文本解码 文本解码是自然语言处理中的一个关键步骤,特别是在任务如机器翻译、文本摘要、自动回复生成等领域。解码过程涉及将编码器(如语言模型、翻译模型等)的输出转换为可读的文本序列。以下是一些常见的文本解码方法和原理: 1. 自回归解码:…...
Base64文件流查看下载PDF方法-CSDN
问题描述 数票通等接口返回的PDF类型发票是以Base64文件流的方式返回的,无法直接查看预览PDF发票, 处理方法 使用第三方在线工具:https://www.jyshare.com/front-end/61/ 在Html代码框中粘贴如下代码 <embed type"application/pd…...
基于TCP的在线词典系统(分阶段实现)(阻塞io和多路io复用(select)实现)
1.功能说明 一共四个功能: 注册 登录 查询单词 查询历史记录 单词和解释保存在文件中,单词和解释只占一行, 一行最多300个字节,单词和解释之间至少有一个空格。 2.功能演示 3、分阶段完成各个功能 3.1 完成服务器和客户端的连接 servic…...
设置DepthBufferBits和设置DepthStencilFormat的区别
1)设置DepthBufferBits和设置DepthStencilFormat的区别 2)Unity打包exe后,游戏内拉不起Steam的内购 3)Unity 2022以上Profiler.FlushMemoryCounters耗时要怎么关掉 4)用GoodSky资产包如何实现昼夜播发不同音乐功能 这是…...
MySQL零散拾遗
mysql中大小写敏感吗? MySQL数据库默认情况下是不区分大小写的,这意味着在查询时,字段名和值的大小写不会影响结果。然而,这种默认行为可能会根据操作系统和配置的不同而有所变化。 在某些操作系统上,比如Linux&…...
kali安装vulhub遇到的问题及解决方法(docker及docker镜像源更换)
kali安装vulhub: 提示:项目地址 https://github.com/vulhub/vulhub 项目安装: git clone https://github.com/vulhub/vulhub.git 安装docker 提示:普通用户请使用sudo: 首先安装 https 协议、CA 证书 apt-get in…...
开源数字人项目Hallo
硬件条件: gpu最低12G 软件: cuda需支持 Python选择3.10吧,我的版本3.11 源码: GitHub - fudan-generative-vision/hallo: Hallo: Hierarchical Audio-Driven Visual Synthesis for Portrait Image Animation models文件&…...
Linux 命令集
修改主机名/关机/重启 1)hostnamectl 命令 $ hostnamectl # 查看操作系统信息(内核、操作系统发行版本、主机名等) $ hostnamectl set-hostname redhatu8 # 修改主机名2)shutdown 关机 $ shutdown -h now # 马上关机3&#…...
QML 鼠标和键盘事件
学习目标:Qml 鼠标和键盘事件 学习内容 1、QML 鼠标事件处理QML 直接提供 MouseArea 来捕获鼠标事件,该操作必须配合Rectangle 获取指定区域内的鼠标事件, 2、QML 键盘事件处理,并且获取对OML直接通过键盘事件 Keys 监控键盘任意按键应的消…...
WPF引入多个控件库使用
目的 设计开发时有的控件库的一部分符合我们想要的UI样式,另一部分来自另一个控件库,想把两种库的样式做一个整合在同一个控件资源上。单纯通过引用的方式会导致原有样式被覆盖。这里通过设置全局样式的方式来实现。 1.安装控件库nuget包:H…...
【Linux】1w详解如何实现一个简单的shell
目录 实现思路 1. 交互 获取命令行 2. 子串分割 解析命令行 3. 指令的判断 内建命令 4. 普通命令的执行 补充:vim 文本替换 整体代码 重点思考 1.getenv和putenv是什么意思 2.代码extern char **environ; 3.内建命令是什么 4.lastcode WEXITSTATUS(sta…...
单目测距 单目相机测距 图片像素坐标转实际坐标的一种转换方案
需要相机位置固定 原图 红色的点是我们标注的像素点,这些红色的点我们知道它的像素坐标,以及以右下角相机位置为原点的x y 实际坐标数值 通过转换,可以得到整个图片内部其余像素点的实际坐标, 这些红色的点是通过转换关系生成的&…...
ensp防火墙综合实验作业+实验报告
实验目的要求及拓扑图: 我的拓扑: 更改防火墙和交换机: [USG6000V1-GigabitEthernet0/0/0]ip address 192.168.110.5 24 [USG6000V1-GigabitEthernet0/0/0]service-manage all permit [Huawei]vlan batch 10 20 [Huawei]int g0/0/2 [Huawei-…...
【大模型LLM面试合集】大语言模型基础_Word2Vec
Word2Vec 文章来源:Word2Vec详解 - 知乎 (zhihu.com) 1.Word2Vec概述 Word2Vec是google在2013年推出的一个NLP工具,它的特点是能够将单词转化为向量来表示,这样词与词之间就可以定量的去度量他们之间的关系,挖掘词之间的联系。 …...
未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...
C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...
智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
