关于对ThreadLocal的理解和作用(通过JWT令牌获取当前登录用户的id)

ThreadLocal是java中的一个线程变量,即ThreadLocal填充的变量属于当前线程,该变量对其他线程而言是隔离的。

基于这个作用,我们可以利用ThreadLocal去解决如何通过解析JWT令牌获取当前登录用户id的问题 。

新建一个工具类BaseContext,里面创建了一个ThreadLocal的对象,并编写了 setCurrentId(),getCurrentId()以及removeCurrentId()方法。

public class BaseContext {

    public static ThreadLocal<Long> threadLocal = new ThreadLocal<>();

    public static void setCurrentId(Long id) {
        threadLocal.set(id);
    }

    public static Long getCurrentId() {
        return threadLocal.get();
    }

    public static void removeCurrentId() {
        threadLocal.remove();
    }

}

并在JWT令牌解析处,使用工具类的setCurrentId()方法即可将用户的id存储到该线程对象中。

//1、从请求头中获取令牌
        String token = request.getHeader(jwtProperties.getAdminTokenName());

        //2、校验令牌
        try {
            log.info("jwt校验:{}", token);
            Claims claims = JwtUtil.parseJWT(jwtProperties.getAdminSecretKey(), token);
            Long empId = Long.valueOf(claims.get(JwtClaimsConstant.EMP_ID).toString());
            log.info("当前员工id:", empId);
            //解析jwt令牌,将当前员工id存储到线程对象中
            BaseContext.setCurrentId(empId);
            //3、通过,放行
            return true;
        } catch (Exception ex) {
            //4、不通过,响应401状态码
            response.setStatus(401);
            return false;
        }

 如需使用该用户id,即可在使用处,利用getCurrentId()方法将id获取出来。(如使用该id插入到数据库某些字段中)

//设置为当前登录用户的id
        employee.setCreateUser(BaseContext.getCurrentId());
        employee.setUpdateUser(BaseContext.getCurrentId());

        //调用employeeMapper的insert方法添加员工信息
        employeeMapper.insert(employee);

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ThreadLocalJava中的一个类,可以在多线程环境下为每个线程提供独立的变量副本。通过使用ThreadLocal,我们可以在拦截器中解析token获取用户的信息,并将用户信息存入ThreadLocal对象中,以便在整个请求的生命周期内随时获取当前线程的用户信息。 具体实现步骤如下: 1. 首先,编写一个ThreadLocal工具类,例如UserUtils,该类包含一个私有的ThreadLocal对象,用于存储用户信息。该类提供了set、get和remove方法,分别用于将用户信息放入ThreadLocal获取当前线程中的用户信息和删除当前线程中的用户信息。 2. 在拦截器中,解析token获取用户的信息,并调用UserUtils的set方法将用户信息放入ThreadLocal中。 3. 在需要获取用户信息的地方,调用UserUtils的get方法即可获取当前线程中的用户信息。 4. 在请求结束后,需要调用UserUtils的remove方法删除当前线程中的用户信息,以防止内存泄漏。 示例代码如下: ```java // UserUtils.java public class UserUtils { private static final ThreadLocal<User> LOCAL = new ThreadLocal<>(); private UserUtils() {} public static void set(User user) { LOCAL.set(user); } public static User get() { return LOCAL.get(); } public static void remove() { LOCAL.remove(); } } // 拦截器中的代码 public class AuthInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 解析token获取用户信息 User user = parseToken(request); // 将用户信息放入ThreadLocal UserUtils.set(user); return true; } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // 请求结束后,删除ThreadLocal中的用户信息 UserUtils.remove(); } } // 在需要获取用户信息的地方 User user = UserUtils.get(); ``` 通过以上步骤,我们可以在拦截器中解析token获取用户的信息,并将用户信息存入ThreadLocal对象中。在整个请求的生命周期内,我们可以随时通过UserUtils.get()方法获取当前线程中的用户信息。 #### 引用[.reference_title] - *1* *2* [ThreadLocal获取用户信息](https://blog.csdn.net/qq_38737586/article/details/118661699)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [ThreadLocal实现登录(保存用户登录信息)](https://blog.csdn.net/qq_56851614/article/details/125464270)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值