Java 在利用MongoDB支持的spring会话的spring引导应用程序中获取当前会话
我有一个Java 在利用MongoDB支持的spring会话的spring引导应用程序中获取当前会话,java,spring,spring-session,Java,Spring,Spring Session,我有一个HandlerInterceptorAdapter的实例,它拦截了检查语言环境的请求 public class LocaleControllerInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Obje
HandlerInterceptorAdapter
的实例,它拦截了检查语言环境的请求
public class LocaleControllerInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
final HttpSession session = SessionContextHolder.getSession();
// ...
}
}
我的SessionContextHolder
是:
public abstract class SessionContextHolder {
public static HttpSession getSession() {
ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
return attr.getRequest().getSession(true);
}
}
当我想调用端点时,拦截器的preHandle()方法将被调用2次(为什么?!),在第一次调用中,SessionContextHolder
给我的会话(通过getSession()
方法)是org.apache.catalina.session.StandardSessionFacade
的一个实例,第二次是org.springframework.session.data.mongo.MongoExpiringSession的一个实例。
我已经通过@EnableMongoHttpSession
注释启用了MongoHttpSession。
问题是,我希望会话应该始终是MongoExpiringSession
的实例,但事实并非如此
有人能解释春季会议的机制和这种行为的原因吗?真奇怪;我认为不应该叫它两次。Spring会话的工作原理是使用标准的servlet过滤器替换请求上下文中的会话。另外,为什么不简单地使用
request.getSession
?让事情变得更复杂,使用你现有的装置。谢谢@chrylis的评论。我也在想。我测试了好几次,它总是调用两次。但这段代码是一个大项目的一部分,有超过50k行代码和几个拦截器,我想我应该检查项目的另一部分来找出原因!这可能是个坏主意,因为这将整个代码库与web层联系在一起。你真的需要它吗?Spring已经有了LocaleContextHolder
来获取当前的Locale
,并且它与LocaleResolver
集成在一起,感觉有点像是在尝试将自己的东西栓在已经支持的东西之上(更容易)LocaleContextHolder
确实使用了ThreadLocal
,但是您的理解是错误的。ThreadLocal
根据当前请求期间从LocaleResolver
检索的值填充。现在巧合的是,有一个SessionLocaleResolver
,它基本上完成了您(再次)试图实现的目标。这与DispatcherServlet结合起来就可以满足您的所有需要。