当前位置: 首页 > news >正文

个人博客开发问题记录:ThreadLocal获取用户数据失败

项目场景:

在用户登录成功后将用户ID存入了ThreadLocal之中便于后续程序直接获取用户数据


问题描述

在用户登录成功后将用户ID存入了ThreadLocal之中,但是后续在其它请求获取ThreadLocal中的值的时候发现都是null


原因分析:

        由于Tomcat是多线程处理请求,所以前端的异步请求导致,登录的请求和其它请求不是同一个线程处理,导致获取不到ThreadLocal中的值


解决方案:

        由于是第一次自己使用ThreadLocal所以搞错了ThreadLocal存储用户数据的位置。

直接在LoginController中设置ThreadLocal中的用户数据会导致其它请求获取不到。应该将设置ThreadLocal存储数据的位置调整到拦截器中,这样一个就可以获取到用户数据了。

        总结一句话:需要使用ThreadLocal数据的请求不能直接放行,需要在拦截器内设置ThreadLocal中的数据,并且在使用结束后释放资源

参考代码:

        ThreadLocalUtils

public class ThreadLocalUtils {private static final ThreadLocal<String> CURRENT = new InheritableThreadLocal<>();public static void setUserInfo(String userRuntime) {CURRENT.set(userRuntime);}public static String getUserInfo() {return CURRENT.get();}public static void clearUserInfo() {CURRENT.remove();}}

        LoginInterceptor

public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 放行OPTIONS请求if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {return true;}// 其他拦截逻辑(如登录校验)String token = request.getHeader("Authorization");log.info("拦截器获取到的token:{}", token);if (token == null || token.isEmpty()) {throw new AuthenticationExceptions(HTTPStateCodeEnum.AUTHENTICATION_FAIL.getMessage());}// 校验token合法性if (!JWTUtils.verify(token)) {throw new AuthenticationExceptions(HTTPStateCodeEnum.AUTHENTICATION_FAIL.getMessage());}// 将用户信息存入ThreadLocalThreadLocalUtils.setUserInfo(String.valueOf(JWTUtils.decodeToken(token)));return true;}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e) throws Exception {if (ThreadLocalUtils.getUserInfo() != null) {ThreadLocalUtils.clearUserInfo();}}
}

http://www.lqws.cn/news/586225.html

相关文章:

  • 《用奥卡姆剃刀原理,为前端开发“减负增效”》
  • CentOS 7 8 安装 madam
  • LLaMA-Factory框架之参数详解
  • (LangChain)RAG系统链路之嵌入模型Embedding(三)
  • spring-ai 工作流
  • 深入理解CSS定位:掌握网页布局的核心技术
  • SpringBoot 启动入口深度解析:main方法执行全流程
  • 【Python使用】嘿马云课堂web完整实战项目第2篇:CMS页面管理需求,后端工程搭建【附代码文档】
  • C++ 安装使用教程
  • Git命令使用心得
  • LeetCode 594. 最长和谐子序列
  • if __name__ == ‘__main__‘:
  • 【嵌入式ARM汇编基础】-ELF文件格式内部结构详解(三)
  • IDEA相关配置记录
  • 对selenium进行浏览器和驱动进行配置Windows | Linux
  • 【机器学习第四期(Python)】LightGBM 方法原理详解
  • Excel Report
  • Photoshop 插件 NBP Freqsep Control 2.0 安装全流程
  • C++ Programming Language —— 第4章:程序流程结构
  • 【启发式算法】Dynamic A*(D*)算法详细介绍(Python)
  • 「Java流程控制」while循环
  • 3.前端和后端参数不一致,后端接不到数据的解决方案
  • Redis 和 Mysql 如何保证数据一致性
  • [Python 基础课程]变量
  • 如何通过SSL证书配置防止源站IP泄露 - 全面防护指南
  • 源码包安装haproxy(rocky8)
  • Kafka 核心机制面试题--自问自答
  • 本地部署kafka4.0
  • PHP中的异常处理try-catch语句
  • Franka机器人赋能RoboCulture研究,打造生物实验室智能解决方案