Java 集装箱';s会话对象,而不是GemFire';在Servlet筛选器中调用的会话对象
当试图访问GemFire会话对象时,它从自定义Servlet过滤器中获取容器的会话对象。会话对象的类型为:Java 集装箱';s会话对象,而不是GemFire';在Servlet筛选器中调用的会话对象,java,spring,spring-session,gemfire,spring-data-gemfire,Java,Spring,Spring Session,Gemfire,Spring Data Gemfire,当试图访问GemFire会话对象时,它从自定义Servlet过滤器中获取容器的会话对象。会话对象的类型为: org.apache.catalina.session。StandardSessionFacade@517957e2 但是从控制器,它工作正常。会话对象的类型为: org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper$HttpSessionWrapper@5a
org.apache.catalina.session。StandardSessionFacade@517957e2
但是从控制器
,它工作正常。会话对象的类型为:
org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper$HttpSessionWrapper@5afe18ce
关于我们如何配置GemFire:
我们有一个遗留的零售应用程序。最重要的是,我们使用了GemFire的2.0.5
版本。在WebAppInitializer启动时
由于springSessionRepositoryFilter
bean未添加到过滤器链中,因此我们必须使用以下命令使用DelegatingFilterProxy
显式注册过滤器:
FilterRegistration.Dynamic springSessionRepositoryFilter =
container.addFilter("springSessionRepositoryFilter", DelegatingFilterProxy.class);
springSessionRepositoryFilter.addMappingForUrlPatterns(
EnumSet.allOf(DispatcherType.class), false, "/*");
在数据处理方面,为了获取会话对象,我们有一个getSession方法,它返回一个会话对象:
ServletRequestAttributes attr =
(ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
HttpSession session = attr.getRequest().getSession();
当我们从Controller
调用getSession()
方法时,它的工作完全符合设计要求。但是从Servlet过滤器调用相同的函数最终会得到容器创建的会话对象
非常感谢您的帮助
根据@John Blum的评论进行了修改,但仍然面临相同的问题。简而言之,为了(特别是,(SSDG)完成其工作,
SessionRepositoryFilter
(,)必须是在(Web)应用程序容器中注册时过滤器链中的第一个Servlet过滤器(例如ApacheTomcat、Eclipse Jetty等)
否则,如果Spring会话的SessionRepositoryFilter
不是过滤器链中的第一个Servlet过滤器,那么Spring会话将不会截获HTTP请求,也无法利用它的机会来替换容器会话(通过使用SessionRepositoryFilter.SessionRepositoryRequestWrapper
包装HttpServletRequest
,请参阅)使用Spring Session使用适当的提供程序提供的会话(例如,使用SSDG的GemFire),由SessionRepository
实现确定,该实现在SessionRepositoryFilter
()上设置
SpringWebMVC应用程序Controller
工作的原因是,JavaEEservlet规范/容器保证在使用HTTP请求调用任何Servlet之前调用所有Servlet过滤器(即HttpServletRequest
)。而且,由于Spring Web MVCDispatcherServlet
是一个合适的HttpServlet
,并负责调用应用程序定义的Spring Web MVC控制器
,因此应用程序控制器
保证可以看到“替换”的HTTP请求(扩展为HTTP会话对象)
所以,有一些家政用品……我(确切地)不确定你说的是什么意思:
2.0.5
版本的GemFire。2.0.5
是指关键GemFire的最新/最新版本的春季课程
和webappinitializer
对于#2,您的意思是专门创建了一个Spring来显式地手动注册SessionRepositoryFilter
(如上代码片段所示)
您知道吗,Spring会话已经提供了这样一个类
这个类负责使用Spring的DelegatingFilterProxy
类注册SessionRepositoryFilter
(,then,and)(注意insertBeforeOtherFilters
实例变量,它默认为true
),并且顺序正确
有趣的是,看起来您在上面的过滤器注册代码片段中做了相同或类似的事情
注意:此(Servlet容器的编程配置)仅适用于Servlet3.0容器和更高版本
例如,您可以看到Spring会话的AbstractHttpServletApplicationInitializer
是如何在中使用的
我注意到SpringDelegatingFilterProxy
类注册(以SessionRepositoryFilter
bean命名,名为“springSessionRepositoryFilter”)的一个不同之处是,您将DelegatingFilterProxy.class
作为servletContext.addFilter(“filterName”)的第二个参数传递给;
,如图所示
FilterRegistration.Dynamic springSessionRepositoryFilter =
container.addFilter("springSessionRepositoryFilter", DelegatingFilterProxy.class);
但是,Spring会话(core)本身(使用“springSessionRepositoryFilter”bean名称)实际上是SpringDelegatingFilterProxy
类的一个实例,并且在注册时将该“实例”添加到ServletContext.addFilter(…)
方法(第二个参数)
我怀疑ServletContext.addFilter(..)
API本身在构造/初始化实例时只使用了SpringDelegatingProxyFilter
类的默认构造函数,这可能是问题的根源,尤其是在以编程方式注册Servlet过滤器时
值得深思
希望这有帮助!在尝试了这些建议后,问题仍然存在。现在,我们不再为SessionRepositoryFilter
单独注册。我们现在使用:
class WebAppInitializer extends AbstractHttpSessionApplicationInitializer {
public WebAppInitializer() {
super(GemfireConfig.class,X.class, Y.class); //X&Y are preexisting config classes in the application context
}
@Override
public void onStartup(ServletContext container) throws ServletException {
super.onStartup(container); // newly added inorder to call AbstractHttpSessionApplicationInitializer.startup()
...//existing code
...//
}
删除了springSessionRepositoryFilter的显式注册
当我们查看堆栈跟踪时,我们可以看到这个过滤器首先被调用。因此,过滤器链的顺序看起来是完整的
我们面临的问题是,过滤器在之后被调用。即使没有提到的更改,这也是相同的行为
不过,筛选器中的会话对象来自容器。您不需要
class WebAppInitializer extends AbstractHttpSessionApplicationInitializer {
public WebAppInitializer() {
super(GemfireConfig.class,X.class, Y.class); //X&Y are preexisting config classes in the application context
}
@Override
public void onStartup(ServletContext container) throws ServletException {
super.onStartup(container); // newly added inorder to call AbstractHttpSessionApplicationInitializer.startup()
...//existing code
...//
}