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结合起来就可以满足您的所有需要。