写一个springboot的session共享拦截器
以下是一个简单的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。最后,在每个请求结束时,我们清除线程本地变量,以避免任何内存泄漏。
写一个springboot的session共享拦截器并过滤login,logout等接口
以下是一个基于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。
请注意,这里的代码仅仅是基于一个示例,您需要根据您的实际需求来进行修改和扩展。
我用了你上面写的拦截器,为什么请求不进入拦截器