7. WebSession Integration
Spring Session provides transparent integration with Spring WebFlux’s WebSession
. This means that developers can switch the WebSession
implementation out with an implementation that is backed by Spring Session.
7.1 Why Spring Session & WebSession?
We have already mentioned that Spring Session provides transparent integration with Spring WebFlux’s WebSession
, but what benefits do we get out of this? As with HttpSession
, Spring Session makes it trivial to support clustered sessions without being tied to an application container specific solution.
7.2 WebSession with Redis
Using Spring Session with WebSession
is enabled by simply registering a WebSessionManager
implementation backed by Spring Session’s ReactiveSessionRepository
. The Spring configuration is responsible for creating a WebSessionManager
that replaces the WebSession
implementation with an implementation backed by Spring Session. Add the following Spring Configuration:
@EnableRedisWebSession (1)
public class SessionConfiguration {
@Bean
public LettuceConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(); (2)
}
}
- (1) The
@EnableRedisWebSession
annotation creates a Spring Bean with the name ofwebSessionManager
that implements theWebSessionManager
. This is what is in charge of replacing theWebSession
implementation to be backed by Spring Session. In this instance Spring Session is backed by Redis. - (2) We create a
RedisConnectionFactory
that connects Spring Session to the Redis Server. We configure the connection to connect to localhost on the default port (6379) For more information on configuring Spring Data Redis, refer to the reference documentation.
7.3 How WebSession Integration Works
With Spring WebFlux and it’s WebSession
things are considerably simpler for Spring Session to integrate with, compared to Servlet API and it’s HttpSession
. Spring WebFlux provides WebSessionStore
API which presents a strategy for persisting WebSession
.
Note
This section describes how Spring Session provides transparent integration with WebSession
. The intent is so that user’s can understand what is happening under the covers. This functionality is already integrated and you do NOT need to implement this logic yourself.
First we create a custom SpringSessionWebSession
that delegates to Spring Session’s Session
. It looks something like the following:
public class SpringSessionWebSession implements WebSession {
enum State {
NEW, STARTED
}
private final S session;
private AtomicReference<State> state = new AtomicReference<>();
SpringSessionWebSession(S session, State state) {
this.session = session;
this.state.set(state);
}
@Override
public void start() {
this.state.compareAndSet(State.NEW, State.STARTED);
}
@Override
public boolean isStarted() {
State value = this.state.get();
return (State.STARTED.equals(value)
|| (State.NEW.equals(value) && !this.session.getAttributes().isEmpty()));
}
@Override
public Mono<Void> changeSessionId() {
return Mono.defer(() -> {
this.session.changeSessionId();
return save();
});
}
// ... other methods delegate to the original Session
}
Next, we create a custom WebSessionStore
that delegates to the ReactiveSessionRepository
and wraps Session
into custom WebSession
implementation:
public class SpringSessionWebSessionStore<S extends Session> implements WebSessionStore {
private final ReactiveSessionRepository<S> sessions;
public SpringSessionWebSessionStore(ReactiveSessionRepository<S> reactiveSessionRepository) {
this.sessions = reactiveSessionRepository;
}
// ...
}
In order to be detected by Spring WebFlux, this custom WebSessionStore
needs to be registered with ApplicationContext
as bean named webSessionManager
. For additional information on Spring WebFlux, refer to the Spring Framework Reference Documentation.