2 回答
TA贡献1877条经验 获得超1个赞
简而言之,为了让Spring Session,特别是用于 Pivotal GemFire (SSDG) 的Spring Session来完成它的工作,SessionRepositoryFilter
( Javadoc , Source )在向您的 (Web) 注册时必须是过滤器链中的第一个Servlet 过滤器应用程序容器(例如 Apache Tomcat、Eclipse Jetty 等)。
否则,如果Spring Session SessionRepositoryFilter
不是过滤器链中的第一个 Servlet 过滤器,那么Spring Session将不会(还)拦截 HTTP 请求,并且将无法行使替换 Container 会话的机会(通过HttpServletRequest
用SessionRepositoryFilter.SessionRepositoryRequestWrapper
,请参阅此处) 使用Session
由Spring Session提供的使用适当的提供程序(例如 GemFire 和 SSDG),由SessionRepository
在SessionRepositoryFilter
(此处)上设置的实现确定。
您的 Spring Web MVC 应用程序Controller
工作的原因是,Java EE Servlet Spec/Container 保证在使用 HTTP 请求(即HttpServletRequest
)调用任何 Servlet 之前调用所有 Servlet 过滤器。并且,由于 Spring Web MVCDispatcherServlet
是一个适当的HttpServlet
并且负责调用您的应用程序定义的 Spring Web MVC Controllers
,因此应用程序Controllers
可以保证看到“替换”的 HTTP 请求(以及扩展的 HTTP 会话对象)。
所以,一些内务管理项目......我不确定(完全)你的意思是:
2.0.5
GemFire 的版本。2.0.5
指的是Pivotal GemFire的Spring Session的最新/当前版本。和
webappinitializer
?
对于#2,您的意思是您专门创建了一个 SpringWebApplicationInitializer
来显式注册SessionRepositoryFilter
, 手动(如上面的代码片段所示)?
你知道春季会议已经提供了这样一类... o.s.session.web.context.AbstractHttpServletApplicationInitializer
。
这个类负责注册SessionRepositoryFilter
using Spring 的DelegatingFilterProxy
类(这里,然后这里和这里(注意insertBeforeOtherFilters
实例变量,默认为true
),并以正确的顺序,这里,嗯,具体来说,这里)。
有趣的是,在上面的过滤器注册代码片段中,您似乎正在做相同或相似的事情。
注意:这(Servlet 容器的编程配置)仅适用于 Servlet 3.0 容器及更高版本。
您可以在示例中看到Spring Session 是 如何AbstractHttpServletApplicationInitializer
使用的,例如,这里。有关更多详细信息,请参见示例的相应指南文档。Initializer
我注意到的关于您的 SpringDelegatingFilterProxy
类注册(以SessionRepositoryFilter
bean 命名,名为“springSessionRepositoryFilter”)的不同之处是,您将 传递给DelegatingFilterProxy.class
的第二个参数servletContext.addFilter("filterName", <FilterType>);
,如下所示...
FilterRegistration.Dynamic springSessionRepositoryFilter = container.addFilter("springSessionRepositoryFilter", DelegatingFilterProxy.class);
然而,春季会议(核心)本身实际上构造并初始化(与“springSessionRepositoryFilter”豆名)春天的一个实例DelegatingFilterProxy
类,并通过该“实例”的ServletContext.addFilter(..)
有关登记方法(第二个参数)。
我怀疑ServletContext.addFilter(..)
API 本身DelegatingProxyFilter
在构造/初始化实例时仅使用 Spring类的默认构造函数,这可能是您问题的根源,尤其是在以编程方式注册 Servlet 过滤器时。
深思熟虑。
希望这可以帮助!
TA贡献1906条经验 获得超3个赞
在尝试了这些建议后,问题仍然存在。现在,我们不再对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 的显式注册。
当我们查看堆栈跟踪时,我们可以看到这个过滤器首先被调用。因此,过滤器链的顺序似乎是完整的。
我们遇到问题的过滤器正在被调用。即使没有提到的更改,这也是相同的行为。
尽管如此,过滤器中的会话对象仍来自容器。
添加回答
举报