In a nutshell, in order for Spring Session, and specifically, Spring Session for Pivotal GemFire (SSDG), to do its job, the SessionRepositoryFilter
(Javadoc, Source) must be the first Servlet Filter in the filter chain when registered with your (Web) Application Container (e.g. Apache Tomcat, Eclipse Jetty, etc).
Otherwise, if Spring Session's SessionRepositoryFilter
is not the first Servlet Filter in the filter chain, then Spring Session will not have intercepted the HTTP request (yet) and won't be able to exercise its opportunity to replace the Container session (by wrapping the HttpServletRequest
with SessionRepositoryFilter.SessionRepositoryRequestWrapper
, see here) with a Session
provided by Spring Session using the appropriate provider (e.g. like GemFire with SSDG), as determined by the SessionRepository
implementation, which is set on the SessionRepositoryFilter
(here).
The reason why your Spring Web MVC application Controller
works is, the Java EE Servlet Spec/Container guarantees that all Servlet Filters are invoked before any Servlets are called with the HTTP request (i.e. HttpServletRequest
). And, since the Spring Web MVC DispatcherServlet
is a proper HttpServlet
and is responsible for invoking your application-defined Spring Web MVC Controllers
, then the application Controllers
are guaranteed to see the "replaced" HTTP request (and by extension, HTTP session object).
So, a few housekeeping items... I am not (exactly) certain what you mean by:
2.0.5
version of GemFire. 2.0.5
refers to the latest/current version of Spring Session for Pivotal GemFire.
And webappinitializer
?
For #2, did you mean that you specifically created a Spring WebApplicationInitializer
to explicitly register the SessionRepositoryFilter
, manually (as shown above in your code snippet)?
Did you know that Spring Session already provides such a class... o.s.session.web.context.AbstractHttpServletApplicationInitializer
.
This class is responsible for registering the SessionRepositoryFilter
using Spring's DelegatingFilterProxy
class (here, then here, and here (notice the insertBeforeOtherFilters
instance variable, which defaults to true
), and in the right order, here, well, specifically, here).
Interestingly enough, it seems like you are doing the same, or similar, thing in your snippet of Filter registration code above.
NOTE: this (programmatical configuration of the Servlet container) only works in Servlet 3.0 containers and later.
You can see how Spring Session's AbstractHttpServletApplicationInitializer
gets used in the samples, for instance, here. More details on the Initializer
are in the corresponding guide docs for the sample.
One thing different about your Spring DelegatingFilterProxy
class registration (named after the SessionRepositoryFilter
bean, named "springSessionRepositoryFilter") that I noticed was, you are passing in the DelegatingFilterProxy.class
as the second argument to servletContext.addFilter("filterName", <FilterType>);
, as shown here...
FilterRegistration.Dynamic springSessionRepositoryFilter =
container.addFilter("springSessionRepositoryFilter", DelegatingFilterProxy.class);
However, Spring Session (core) itself actually constructs and initializes (with the "springSessionRepositoryFilter" bean name) an instance of the Spring DelegatingFilterProxy
class and passes that "instance" to the ServletContext.addFilter(..)
method (2nd argument) on registration.
I suspect the ServletContext.addFilter(..)
API itself just uses the default constructor of the Spring DelegatingProxyFilter
class when constructing/initializing an instance, which is probably the root of your problem, especially when registering the Servlet Filter programmatically.
Food for thought.
Hope this helps!