HttpServletRequest 和 HttpServletResponse 不同JDK版本的引入

java中,可能会用到JWT令牌校验,
这时,大概率会用到 HttpServletRequest,和 HttpServletResponse

若为 JDK8SpringBoot 2.7.3 的版本则引入:

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

若是 JDK17, SpringBoot 3.4.0 或更高的版本,则为:

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

我出现这个问题的时候,是从哔哩哔哩上找了个项目,打算学习一下,但视频中用的是JDK8,而我用的JDK17,所以在这里记录一下。

拦截器

import cn.hutool.core.util.ObjectUtil;
import com.Jwt工具类.JwtUtil;
import com.ThreadLocal工具类.ThreadLocalUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.common.exception.ServiceException;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import java.util.Map;

/**
 * 拦截器
 */
@RequiredArgsConstructor
@Component //注入到IOC容器里
public class LoginInterceptor implements HandlerInterceptor {

    private final StringRedisTemplate stringRedisTemplate;

    //preHandle : 在……之前处理
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        //令牌验证
        String token = request.getHeader("Authorization");

        //验证 token
        try {
            //从redis中获取相同的token
            ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();

            //根据redis键值对的键,获取对应的值
            String redisToken = operations.get(token);

            if (ObjectUtil.isNull(redisToken)){
                //token失效了
                throw new RuntimeException();
            }

            Map<String, Object> map = JwtUtil.paresToken(token);
            //把业务数据存储到ThreadLocal中
            ThreadLocalUtil.set(map);

            //放行
            return true;
        } catch (Exception e) {
            //http响应状态码401
            response.setStatus(401);

            //不放行
            throw new ServiceException("登录状态已失效,请重新登录");

        }
    }

    //afterCompletion 在……之后处理
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        //清空ThreadLocalUtil中的数据,防止内存泄露
        ThreadLocalUtil.remove();
    }
}

JWT工具类:

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;

import java.util.Date;
import java.util.Map;

public class JwtUtil {
    private static final String KEY = "event";

    //接受业务数据,生成token并返回
    public static String genToken(Map<String, Object> claims) {
        // 创建 JWT 构建器
        return JWT.create()
                // 将传入的 claims 放入 token 中,键名为 "claims"
                .withClaim("claims", claims)
                // 设置过期时间为 当前时间加 3 小时
                .withExpiresAt(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 3))
                // 使用 HMAC256 算法,并用 "event" 作为密钥进行签名
                .sign(Algorithm.HMAC256(KEY));

    }

    //接受token, 验证token, 并返回业务数据
    public static Map<String, Object> paresToken(String token) {
        return JWT.require(Algorithm.HMAC256(KEY))
                .build()
                .verify(token)
                .getClaim("claims")
                .asMap();
    }
}

ThreadLocal工具类:

ThreadLocal 用来为每个线程提供独立的变量副本,从而实现线程隔离。使每个线程独立地操作自己的变量副本,而不会影响其他线程的副本。
ThreadLocal 的主要作用是解决多线程环境下共享变量的线程安全问题。它通过为每个线程维护一个独立的变量副本,避免了线程之间的竞争和同步问题。

注意事项

  • 避免滥用:ThreadLocal 适用于线程隔离的场景,但不适合存储大量数据,否则可能会导致内存泄漏。

  • 清理资源:在使用线程池时,务必在任务执行完毕后调用 ThreadLocal.remove(),以防止内存泄漏。

  • 线程池中的问题:如果线程池中的线程被复用,且 ThreadLocal 变量没有被清理,可能会导致数据错乱。

public class ThreadLocalUtil {
    private static final ThreadLocal THREAD_LOCAL = new ThreadLocal();

    //根据键获取值
    public static <T> T get(){
        return (T) THREAD_LOCAL.get();
    }

    //存储键值对
    public static void set(Object value){
        THREAD_LOCAL.set(value);
    }

    //清除ThreadLocal 防止内存泄露
    public static void remove(){
        THREAD_LOCAL.remove();
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/982558.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SLAM评估工具安装及使用EVO(Ubuntu20.04安装evo)--缺少 onnx 库还有Pandas 版本不兼容解决

介绍一下我的是ubuntu20.04.机载电脑是orinnx&#xff0c;通过源码烧写的系统。 首先打开终端&#xff0c;输入 pip install evo --upgrade --no-binary evo 安装过程中出现如下问题 缺少 onnx 库还有Pandas 版本不兼容&#xff0c; ONNX&#xff08;Open Neural Network E…

Arcgis中添加脚本工具箱

文章目录 准备资料1、打开arcmap2、找到目录窗口3、复制粘贴工具箱的路径4、添加或者确认python脚本路径准备资料 (1)工具箱 (2)python脚本 1、打开arcmap 2、找到目录窗口 3、复制粘贴工具箱的路径 4、添加或者确认python脚本路径 脚本上右键属性(注意:脚本内容和路径…

第二次CCF-CSP认证(思路及源码)

第二次CCF-CSP认证 第一道&#xff08;easy&#xff09;思路及AC代码 第二道&#xff08;easy&#xff09;基本思路及AC代码 第三道&#xff08;mid&#xff09;基本思路及AC代码solution 1 (模拟)solution 2&#xff08;KMP&#xff09; 第一道&#xff08;easy&#xff09; 题…

RAGflow 无法加载Embedding模型

部署0.17版本的RAGflow&#xff0c;在模型列表中已经添加了嵌入模型&#xff0c;但是知识库配置时&#xff0c;嵌入模型灰显&#xff1a; 问题原因&#xff1a; 提前上传了一个文档&#xff0c;在知识库有文档之后&#xff0c;就不能够修改嵌入模型了。删除文档之后&#xff0…

C++ Primer 拷贝、赋值与销毁

欢迎阅读我的 【CPrimer】专栏 专栏简介&#xff1a;本专栏主要面向C初学者&#xff0c;解释C的一些基本概念和基础语言特性&#xff0c;涉及C标准库的用法&#xff0c;面向对象特性&#xff0c;泛型特性高级用法。通过使用标准库中定义的抽象设施&#xff0c;使你更加适应高级…

【够用就好006】如何从零开发游戏上架steam面向AI编程的godot独立游戏制作实录001流程

记录工作实践 这是全新的系列&#xff0c;一直有个游戏制作梦 感谢AI时代&#xff0c;让这一切变得可行 长欢迎共同见证&#xff0c;期更新&#xff0c;欢迎保持关注&#xff0c;待到游戏上架那一天&#xff0c;一起玩 面向AI编程的godot独立游戏制作流程实录001 本期是第…

计算机毕业设计Python+DeepSeek-R1大模型空气质量预测分析(源码+文档+PPT+讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

【文生图】windows 部署stable-diffusion-webui

windows 部署stable-diffusion-webui AUTOMATIC1111 stable-diffusion-webui Detailed feature showcase with images: 带图片的详细功能展示: Original txt2img and img2img modes 原始的 txt2img 和 img2img 模式 One click install and run script (but you still must i…

单片机项目复刻需要的准备工作

一、前言 复刻单片机的项目的时候&#xff0c;有些模块是需要焊接的。很多同学对焊接没有概念。 这里说一下做项目的基本工具。 比如&#xff1a;像这种模块&#xff0c;都需要自己焊接了排针才可以链接的。 二、基本模块 2.1 单排排针 一些模块买回来是没有焊接的&#x…

微服务概览与治理

微服务概览与治理 1. 微服务架构的演进 1.1 引言 当我们讨论微服务时&#xff0c;我们并不是在谈论一种炫酷的新技术&#xff0c;而是在寻找一种更好的方式来组织我们的软件系统&#xff0c;使其更易扩展、更易维护。软件架构的发展历程往往是对业务需求和技术挑战的回应。从…

《代码随想录第五十七天》——孤岛的总面积、沉没孤岛、水流问题、建造最大岛屿

《代码随想录第五十七天》——孤岛的总面积、沉没孤岛、水流问题、建造最大岛屿 本篇文章的所有内容仅基于C撰写。 1. 孤岛的总面积 1.1 题目 孤岛的总面积 题目描述 给定一个由 1&#xff08;陆地&#xff09;和 0&#xff08;水&#xff09;组成的矩阵&#xff0c;岛屿指…

IntelliJ IDEA 华为云远程开发配置步骤

1.连接华为云主机,点击New Project 2.输入用户名与主机IP后连接 3.输入密码授权连接 4.继续连接 注意,远程主机内存最少要4G才能启动后端IDE 5.连接华为云主机成功,下载IDE并连接 选择项目位置

23种设计模式之单例模式(Singleton Pattern)【设计模式】

文章目录 一、简介二、关键点三、实现单例模式的步骤四、C#示例4.1 简单的单例模式4.2 线程安全的单例模式&#xff08;双重检查锁定&#xff09;4.3 静态初始化单例模式 五、单例模式优缺点5.1 优点5.2 缺点 六、适用场景七、示例的现实应用 一、简介 单例模式&#xff08;Si…

c盘爆红后,使用diskgenius给C盘无损扩容,操作记录

diskgenius下载链接 参考链接 操作前环境 之前电脑配置了一个每天定时清理c盘临时文件的脚本&#xff0c;依然阻止不了c盘爆红。 实测DISKGENIUS 无损扩容有效&#xff0c;扩容前的环境&#xff1a; 扩容前&#xff0c;C区可用空间 9G,爆红C盘D盘都是 NTFS 格式&#xff0c;D…

【音视频】ffplay简单过滤器

一、ffplay简单过滤器 视频旋转&#xff1a;借助transpose滤镜 ffplay -i 1.mp4 -vf transpose1这里选择不同的数字是不同的方向&#xff1a; 视频翻转&#xff1a;借助hflip/vflip实现水平和垂直翻转&#xff1a; 水平翻转 ffplay 1.mp4 -vf hflip垂直翻转 ffplay 1.mp4 …

蓝桥杯备考:动态规划路径类dp之迷雾森林

step1 :确定状态表示 f[i][j]表示 n,n 到 i,j的方案数 step2 : 推导状态转移方程初始化 step3 确认填表顺序 应该是从下往上&#xff0c;从左往右 step4:答案在f[1][m] 代码实现&#xff1a; #include <iostream> #include <cstring> using namespace std; i…

零售交易流程相关知识(top-down拆解)

引入 关于POS机交易时的后台数据交互 模块之间数据交换&#xff0c;都可以能被窃取或篡改。由此引入加密、解密机制和签名、验签机制 经典的加密、解密机制&#xff1a; 对称加密&#xff1a;DES\ TDES\ AES\ RC4 非对称加密&#xff1a;RSA\ DSA\ ECC 经典的签名、验签…

threejs:用着色器给模型添加光带扫描效果

第一步&#xff1a;给模型添加光带 首先创建一个立方体&#xff0c;不进行任何缩放平移操作&#xff0c;也不要set position。 基础代码如下&#xff1a; 在顶点着色器代码里varying vec3 vPosition;vPosition position;获得threejs自动计算的顶点坐标插值&#xff08;也就…

数据可携带权的多重价值与实践思考

文章目录 前言一、数据可携带权的提出与立法二、数据可携带权的多重价值1、推动数据要素市场化配置2、促进市场竞争与创新3、强化个人数据权益 三、数据可携带权的实践挑战1、数据安全与隐私保护面临风险2、接口差异导致数据迁移成本高昂3、可携带的数据范围尚存争议 数据可携带…

博客系统自动化测试_测试报告

项目背景 开发出一个专属于自己的博客系统&#xff0c;可以完全按照自己的需求来设计&#xff0c;比如&#xff1a;去掉那些花里胡哨的功能和广告&#xff0c;只保留自己真正需要的&#xff0c;比如文章发布、分类、标签、搜索等。可以根据自己的审美设计界面&#xff0c;想要…