安定.528 2024-06-01 16:00 采纳率: 41.7%
浏览 11

ThreadLocal无法获取当前用户,如何解决?

ThreadLocal无法获取到当前登录用户信息,刷新十遍左右才能获取

我想要达到的效果是,每次访问ThreadLocal的时候,都能获取到当前登录用户的信息

这是控制台显示

可以看出,无法正常获取到当前登录用户的信息,要刷新很多遍才能拿到,并且不能保证下次能拿到

img

自己写的代码如下

这里单独写了一个类,用来存储当前登录用户信息的身份

img

其他逻辑代码不用管,在校验完成登录的时候,将当前登录的用户信息set到ThreadLocal当中

img

然后写了一个rest接口

img

然后直接访问(这里没有做任何的拦截)

img

刷新十遍左右,前端就会弹出当前用户登录的信息,但是后面继续刷新,data继续为null

img

  • 写回答

3条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-06-01 16:00
    关注

    引自免费微信小程序:皆我百晓生

    看起来你在尝试使用Java中的ThreadLocal来存储当前用户的会话信息,但遇到了一些问题。根据你提供的日志和代码片段,问题可能出现在用户信息被设置到ThreadLocal之后的请求处理上。当多个线程同时处理请求时,每个线程都有它自己的ThreadLocal实例,这意味着一个线程看不到另一个线程设置的值。

    要解决这个问题,你需要确保在用户登录验证通过后,正确地将用户信息设置到ThreadLocal中,而且要在整个应用程序的生命周期内,无论哪个线程处理请求,都可以访问到这个信息。一种常见的做法是在过滤器(Filter)中设置ThreadLocal,这样可以在所有请求开始之前就设置好用户信息。下面是一个简单的示例:

    首先,创建一个用于存储用户信息的类,比如DyUser。然后创建一个AuthenticationContext类,用于封装ThreadLocal并提供相关方法。

    // DyUser.java
    public class DyUser {
        // ... 你的DyUser类定义
    }
    
    // AuthenticationContext.java
    public class AuthenticationContext {
        private static final ThreadLocal<DyUser> threadLocal = new ThreadLocal<>();
    
        public static void setContext(DyUser context) {
            threadLocal.set(context);
        }
    
        public static DyUser getContext() {
            return threadLocal.get();
        }
    }
    

    接下来,编写一个过滤器,在过滤器中检查请求是否携带了有效的用户信息,并将其设置到ThreadLocal中:

    import javax.servlet.*;
    import javax.servlet.http.HttpServletRequest;
    import java.io.IOException;
    
    public class UserContextFilter implements Filter {
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            HttpServletRequest req = (HttpServletRequest) request;
            String userId = req.getHeader("Authorization"); // 假设从HTTP头部获取用户ID
    
            // 在这里,你应该有一个方法来根据用户ID从数据库或其他来源获取DyUser对象
            DyUser user = fetchUserFromDatabase(userId);
    
            if (user != null) {
                AuthenticationContext.setContext(user);
            }
    
            chain.doFilter(request, response);
        }
    
        // ... 实现其他Filter接口的方法,例如init()和destroy()
    }
    

    然后,配置Spring MVC应用来使用这个过滤器。在web.xml文件中添加如下配置:

    <filter>
        <filter-name>UserContextFilter</filter-name>
        <filter-class>YourPackage.UserContextFilter</filter-class>
    </filter>
    
    <filter-mapping>
        <filter-name>UserContextFilter</filter-name>
        <url-pattern>/tiktok/*</url-pattern>
    </filter-mapping>
    

    或者如果你使用的是Spring Boot,可以使用Java配置方式:

    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/tiktok/**");
        }
    
        @Override
        public void addFilters(List<ServletFilterRegistrationBean<?>> filters) {
            filters.add(new ServletFilterRegistrationBean<>(new UserContextFilter()));
        }
    }
    

    现在,你应该能够在任何时候通过调用AuthenticationContext.getContext()来获取当前用户的DyUser对象。注意,这只是一个基本的实现,实际项目中你可能需要处理更复杂的情况,比如用户登出、多线程环境下的并发控制等。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 6月1日

悬赏问题

  • ¥15 c#转安卓 java html
  • ¥15 os.listdir文件路径找不到
  • ¥15 使用gojs3.0,如何在nodeDataArray设置好text的位置,再go.TextBlock alignment中进行相应的改变
  • ¥15 psfusion图像融合指标很低
  • ¥15 银河麒麟linux系统如何修改/etc/hosts权限为777
  • ¥50 医院HIS系统代码、逻辑学习
  • ¥30 docker离线安装mysql报错,如何解决?
  • ¥15 构建工单的总账影响在哪里查询或修改
  • ¥15 三个简单项目写完之后有重赏之后联系我
  • ¥15 python报内存不能read错误