为了账号安全,请及时绑定邮箱和手机立即绑定

在 Servlet 过滤器中调用容器的会话对象而不是 GemFire 的会话对象

在 Servlet 过滤器中调用容器的会话对象而不是 GemFire 的会话对象

POPMUISE 2021-09-15 15:39:42
当尝试访问 GemFire 会话对象时,自定义 Servlet 过滤器会使用容器的会话对象。会话对象的类型为:org.apache.catalina.session.StandardSessionFacade@517957e2但是从Controller,它工作正常。会话对象的类型为: org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper$HttpSessionWrapper@5afe18ce关于我们如何配置 GemFire:我们有一个传统的零售应用程序。最重要的是,我们使用了2.0.5GemFire 版本。在webappintializer启动时,AnnotationConfigWebApplicationContext rootContext =     new AnnotationConfigWebApplicationContext();rootContext.register(GemfireConfig.class,RootConfig.class, SecurityConfig.class);由于springSessionRepositoryFilterbean没有添加到过滤器链中,我们必须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();当我们getSession()从Controller它调用该方法时,它按照设计完全正常工作。但是从 Servlet 过滤器调用相同的方法最终会获得容器创建的会话对象。任何帮助深表感谢。根据@John Blum 的评论重新设计,但仍然面临同样的问题。
查看完整描述

2 回答

?
冉冉说

TA贡献1877条经验 获得超1个赞

简而言之,为了让Spring Session,特别是用于 Pivotal GemFire (SSDG) 的Spring Session来完成它的工作,SessionRepositoryFilterJavadoc , Source )在向您的 (Web) 注册时必须是过滤器链中的第一个Servlet 过滤器应用程序容器(例如 Apache Tomcat、Eclipse Jetty 等)。

否则,如果Spring Session SessionRepositoryFilter不是过滤器链中的第一个 Servlet 过滤器,那么Spring Session将不会(还)拦截 HTTP 请求,并且将无法行使替换 Container 会话的机会(通过HttpServletRequestSessionRepositoryFilter.SessionRepositoryRequestWrapper,请参阅此处) 使用SessionSpring Session提供的使用适当的提供程序(例如 GemFire 和 SSDG),由SessionRepositorySessionRepositoryFilter此处)上设置的实现确定。

您的 Spring Web MVC 应用程序Controller工作的原因是,Java EE Servlet Spec/Container 保证在使用 HTTP 请求(即HttpServletRequest)调用任何 Servlet 之前调用所有 Servlet 过滤器。并且,由于 Spring Web MVCDispatcherServlet是一个适当的HttpServlet并且负责调用您的应用程序定义的 Spring Web MVC Controllers,因此应用程序Controllers可以保证看到“替换”的 HTTP 请求(以及扩展的 HTTP 会话对象)。

所以,一些内务管理项目......我不确定(完全)你的意思是:

  1. 2.0.5GemFire 的版本。 2.0.5指的是Pivotal GemFireSpring Session的最新/当前版本。

  2. webappinitializer

对于#2,您的意思是您专门创建了一个 SpringWebApplicationInitializer来显式注册SessionRepositoryFilter, 手动(如上面的代码片段所示)?

你知道春季会议已经提供了这样一类... o.s.session.web.context.AbstractHttpServletApplicationInitializer

这个类负责注册SessionRepositoryFilterusing Spring 的DelegatingFilterProxy类(这里,然后这里这里(注意insertBeforeOtherFilters实例变量,默认为true),并以正确的顺序,这里,嗯,具体来说,这里)。

有趣的是,在上面的过滤器注册代码片段中,您似乎正在做相同或相似的事情。

注意:这(Servlet 容器的编程配置)仅适用于 Servlet 3.0 容器及更高版本。

您可以在示例中看到Spring Session 是 如何AbstractHttpServletApplicationInitializer使用的,例如,这里。有关更多详细信息,请参见示例的相应指南文档Initializer

我注意到的关于您的 SpringDelegatingFilterProxy类注册(以SessionRepositoryFilterbean 命名,名为“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 过滤器时。

深思熟虑。

希望这可以帮助!


查看完整回答
反对 回复 2021-09-15
?
一只名叫tom的猫

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 的显式注册。


当我们查看堆栈跟踪时,我们可以看到这个过滤器首先被调用。因此,过滤器链的顺序似乎是完整的。


我们遇到问题的过滤器正在被调用。即使没有提到的更改,这也是相同的行为。


尽管如此,过滤器中的会话对象仍来自容器。


查看完整回答
反对 回复 2021-09-15
  • 2 回答
  • 0 关注
  • 158 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信