写一个springboot的session共享拦截器

2023-04-14by@17683930536-e9rtC&@ChatGPT.Model: gpt-3.5
17683930536-e9rtC

写一个springboot的session共享拦截器

Avatar
Avatar

以下是一个简单的Spring Boot session共享拦截器,它将会在每个请求中检查session ID是否存在并且有效,如果是,则将其存储在线程本地变量中,以便后续的请求可以共享相同的session。

@Component
public class SessionInterceptor implements HandlerInterceptor {

    private static final ThreadLocal<String> threadLocalSessionId = new ThreadLocal<>();

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String sessionId = request.getHeader("sessionId");
        if (sessionId != null && !sessionId.isEmpty()) {
            // 检查session是否存在
            if (redisTemplate.opsForValue().get(sessionId) != null) {
                // 将session ID存储在线程本地变量中
                threadLocalSessionId.set(sessionId);
                return true;
            }
        }
        // session不存在或已失效,返回错误信息
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid session ID");
        return false;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 清除线程本地变量
        threadLocalSessionId.remove();
    }

    public static String getSessionId() {
        // 返回线程本地变量中的session ID
        return threadLocalSessionId.get();
    }
}

在上面的拦截器中,我们使用了Redis作为session存储介质。在实际应用中,您可以根据需要使用其他存储介质,如数据库或内存。此外,为了确保线程安全,我们使用了线程本地变量来存储session ID,以便每个线程都可以访问自己的session。最后,在每个请求结束时,我们清除线程本地变量,以避免任何内存泄漏。

17683930536-e9rtC

写一个springboot的session共享拦截器并过滤login,logout等接口

Avatar
Avatar

以下是一个基于Spring Boot的session共享拦截器示例,它将检查session ID是否存在并且有效,并过滤掉login、logout等接口,以避免在这些接口中无意间使用session。

@Component
public class SessionInterceptor implements HandlerInterceptor {

    private static final ThreadLocal<String> threadLocalSessionId = new ThreadLocal<>();

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    private static final List<String> EXCLUDE_PATHS = Arrays.asList("/login", "/logout");

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String sessionId = request.getHeader("sessionId");
        String path = request.getServletPath();
        if (!EXCLUDE_PATHS.contains(path)) {
            if (sessionId != null && !sessionId.isEmpty()) {
                // 检查session是否存在
                if (redisTemplate.opsForValue().get(sessionId) != null) {
                    // 将session ID存储在线程本地变量中
                    threadLocalSessionId.set(sessionId);
                    return true;
                }
            }
            // session不存在或已失效,返回错误信息
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid session ID");
            return false;
        }
        // 排除login、logout等接口
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 清除线程本地变量
        threadLocalSessionId.remove();
    }

    public static String getSessionId() {
        // 返回线程本地变量中的session ID
        return threadLocalSessionId.get();
    }
}

在上面的代码中,我们定义了一个列表EXCLUDE_PATHS,其中包含了需要排除的接口。在preHandle方法中,我们检查当前请求是否在排除列表中,如果不是,则执行session ID检查。如果session ID存在并且有效,则将其存储在线程本地变量中。在afterCompletion方法中,我们清除线程本地变量以避免内存泄漏。getSessionId方法用于获取线程本地变量中存储的session ID。

请注意,这里的代码仅仅是基于一个示例,您需要根据您的实际需求来进行修改和扩展。

17683930536-e9rtC

我用了你上面写的拦截器,为什么请求不进入拦截器

Avatar