spring监听请求执行结束,移除当前ThreadLocal数据两种方法
在开发过程中,很多时候我们会使用ThreadLocal来临时缓存数据,当一次数据请求执行完成后需要主动执行释放当前ThreadLocal缓存数据资源,防止未能及时释放导致下一次访问时候ThreadLocal依然保持上一次缓存的数据。
spring提供两种方式去监听一次请求完成事件。
1、HandlerInterceptor -> afterCompletion 使用拦截方式,再执行完成后执行afterCompletion
2、ApplicationListener -> ServletRequestHandledEvent ,ApplicationListener 提供的是监听那种事件类型,ServletRequestHandledEvent 就是一次请求结束后的事件。
通过上述两种方式可以很方便的在一次请求完成移除当前线程ThreadLocal。
ThreadLocal 工具
public class ThreadLocal2UserSessionUtil {private static final ThreadLocal<Object> LOCAL = new ThreadLocal<>();/*** 设置数据** @param paramMap*/public static void set(Map<String, Object> paramMap) {LOCAL.set(paramMap);}/*** 获取值** @return*/public static Map<String, Object> get() {if (Objects.isNull(LOCAL.get())) {return new HashMap<>();} else {return (Map<String, Object>) LOCAL.get();}}/*** 获取值** @return*/public static Object get(String key) {Map<String, Object> resMap = (Map<String, Object>) LOCAL.get();if (null == resMap) {return null;}return (null != resMap.get(key)) ? resMap.get(key) : null;}/*** 每次取出数据后必须清空 否则就会出现值重复*/public static void remove() {LOCAL.remove();}/*** 获取app登录token** @return*/public static String getToken4App() {Map<String, Object> map = get();return (null == map) ? "" : (String) map.get(EncryptReqParamNameConstant.PARAM_TOKEN);}/*** 初始化数值** @return*/public static void pushUserToken4App(String appToken) {Map<String, Object> localMap = get();if (StringUtil.isNotBlank(appToken)) {localMap.put(EncryptReqParamNameConstant.PARAM_TOKEN, appToken);set(localMap);}}/*** 初始化数值** @return*/public static void pushUserId4App(Long userId) {Map<String, Object> localMap = get();if (null != userId) {localMap.put(EncryptReqParamNameConstant.USER_ID, userId);set(localMap);}}/*** 初始化数值 注意这里只有加解密才将用户id放入** @return*/public static Long getUserId4App() {Map<String, Object> map = get();return (null == map) ? null : (Long) map.get(EncryptReqParamNameConstant.USER_ID);}
}
HandlerInterceptor 方式
@Slf4j
@Component
public class ThreadLocalRemoveInterceptor implements HandlerInterceptor {@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {HandlerInterceptor.super.afterCompletion(request, response, handler, ex);ThreadLocal2UserSessionUtil.remove();}
}
在web控制器中加入监听器
@Configuration
public class PathPrefixMvcConfigurer implements WebMvcConfigurer {@Autowiredprivate ThreadLocalRemoveInterceptor threadLocalRemoveInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(threadLocalRemoveInterceptor).addPathPatterns("/*");}
}
2、通过监听器方式
@Slf4j
@Component
public class ServletRequestHandledEventListener implements ApplicationListener<ServletRequestHandledEvent> {@Overridepublic void onApplicationEvent(ServletRequestHandledEvent event) {ThreadLocal2UserSessionUtil.remove();}
}
完成
相关文章:
spring监听请求执行结束,移除当前ThreadLocal数据两种方法
在开发过程中,很多时候我们会使用ThreadLocal来临时缓存数据,当一次数据请求执行完成后需要主动执行释放当前ThreadLocal缓存数据资源,防止未能及时释放导致下一次访问时候ThreadLocal依然保持上一次缓存的数据。 spring提供两种方式去监听一…...
知识图谱--Jena基础操作和检索推理应用
在上一篇读书笔记中讲到知识图谱存储主要有基于开源的Jena方式和基于图数据库(Neo4j)方式,本次主要对Jena的基础操作和如何应用进行了实践总结,同时结合了D2R,将结构化数据转换成Jena可以加载的格式(即RDF,后缀是.nt),Apache Jena作为一种开源的Java语义网框架,主要功…...
GEE python——将GEE ASSETS中存储的影像或者矢量转化为数据格式XEE()
数据转换器是内置于 getPixels、computePixels、listFeatures 和 computeFeatures 中的客户端转换能力。通过指定兼容的文件格式,这些方法可以返回 Python 原生格式的数据,如用于栅格的结构化 NumPy 数组和用于矢量的 Pandas DataFrames 或 GeoPandas GeoDataFrames。对于矢量…...

Java集合框架:List、Set、Map类型及泛型详解
文章目录 📕我是廖志伟,一名Java开发工程师、Java领域优质创作者、CSDN博客专家、51CTO专家博主、阿里云专家博主、清华大学出版社签约作者、产品软文创造者、技术文章评审老师、问卷调查设计师、个人社区创始人、开源项目贡献者。🌎跑过十五…...
Ubuntu 安装 docker
一.添加Docker官方GPG密钥 curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add - 如果出现: The program curl is currently not installed. You can install it by typing: sudo apt install curl 先安装 curl : sudo apt inst…...

BUUCTF zip伪加密 1
BUUCTF:https://buuoj.cn/challenges 题目描述: 下载附件,得到一个zip压缩包。 密文: 解题思路: 1、刚开始尝试解压,看到了flag.txt文件,但需要解压密码。结合题目,确认这是zip伪加密&#…...

p5.js 到底怎么设置背景图?
本文简介 点赞 关注 收藏 学会了 在 《p5.js 光速入门》 里我们学过加载图片元素,学过过背景色的用法,但当时没提到背景图要怎么使用。 本文就把背景图这部分内容补充完整,并且会提到在 p5.js 里使用背景图的一些注意点。 背景图的用法…...

python+unittest+requests+HTMLRunner编写接口自动化测试集
问题描述: 搭建接口测试框架,执行用例请求多个不同请求方式的接口 实现步骤: ① 创建配置文件config.ini,写入部分公用参数,如接口的基本url、测试报告文件路径、测试数据文件路径等配置项 1 [DATABASE] 2 data_addre…...

Vue---监听div元素宽高改变时echart图表重新resize
一、需求描述 当点击上图的红色框时,echart的div元素宽会改变但是无法触发echarts图表的resize重新渲染,对于浏览器而言,浏览器具有window.resize方法监听浏览器窗口大小的改变,而div元素没有监听宽高改变的方法。 二、解决方案 …...
Kubernetes Etcd不可用日志:NOSPACE 的问题修复
两套k8s集群同一天同时出现etcd集群空间超过配额,kubectl get cs时发现所有的etcd均返回503报错,查看etcd的告警发现有NO SPACE的信息且 etcdctl --endpoints${ETCD_ENDPOINT} --cert${ETCD_CERTFILE} --key${ETCD_KEYFILE} --cacert${ETCD_CAFILE} endp…...

分组卷积的思想神了
大家好啊,我是董董灿。 最近,分组卷积帮我解决了一个大忙,事情是这样的。 这几天遇到一个头疼的问题,就是要在某一芯片上完成一个神经网络的适配,这个神经网络中卷积居多,并且有一些卷积的通道数很大&…...

北邮22级信通院数电:Verilog-FPGA(7)第七周实验(2):BCD七段显示译码器(关注我的uu们加群咯~)
北邮22信通一枚~ 跟随课程进度更新北邮信通院数字系统设计的笔记、代码和文章 持续关注作者 迎接数电实验学习~ 获取更多文章,请访问专栏: 北邮22级信通院数电实验_青山如墨雨如画的博客-CSDN博客 关注作者的uu们可以进群啦~ 一.verilog代码 1.1 …...

LVS集群-DR模式
概念: LVS-DR模式,也是最常用的lVS负载方式,DR DIRECT ROUTING 直接路由模式 负载均衡器lVS调度器,只负责请求和转发到后端的真实服务器,但是影响结果,由后端服务器直接转发给客户端,不需要经…...
行为型模式-状态模式
在状态模式中,类的行为是基于它的状态改变的。这种类型的设计模式属于行为型模式。 在状态模式中,我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。 意图:允许对象在内部状态发生改变时改变它的行为࿰…...

html/css/javascript/js实现的简易打飞机游戏
源码下载地址 支持:远程部署/安装/调试、讲解、二次开发/修改/定制 视频浏览地址...

ubuntu 22.04安装百度网盘
百度网盘 客户端下载 (baidu.com) 下载地址 sudo dpkg -i baidunetdisk_4.17.7_amd64.deb...

关于路由转发
路由表的作用 路由表的作用:目标网络匹配路由表,从相应网络转发;不匹配路由表,丢弃或转发至默认路由器。 路由转发的原理 根据IP地址找到目标网络,由应路由器解封装查看目标网络是否可达,重新封装进行转…...
oradebug current_sql
CDB 或者PDB都可以,但是数据库sid不对找不到SQL TEXT ps -ef|grep 3485015 oracle 3485015 1 51 21:19 ? 00:01:10 oracle (LOCALNO) oracle 3489325 3488836 0 21:21 pts/0 00:00:00 grep --colorauto 3485015 . oraenv [oracle~]$ s SQL*…...

JSON(详解)
目录 什么是JSON? 哪里会用到JSON? JSON的特点 JSON的优点 JSON的缺点 JSON和cJSON的关系 什么是JSON? JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。它以易于阅读和编写的文本格式来存储和表示…...

1-多媒体通信概述
文章目录 媒体和多媒体媒体多媒体VarityIntergrationInteraction 多媒体通信(MMC)业务类型 MMC主要问题和关键技术主要问题关键技术 MMC发展动向重要事件趋势 标准化组织 媒体和多媒体 媒体 承载信息的载体. 感知媒体, 表示媒体, 显示媒体, 存储媒体, 传输媒体. 多媒体 Var…...

Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...

el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...

ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...