Add EnableSpringHttpSession
Fixes gh-231
This commit is contained in:
@@ -321,6 +321,22 @@ It is the responsibility of the developer to ensure the attribute is populated s
|
||||
Some `SessionRepository` implementations may choose to implement `FindByUsernameSessionRepository` also.
|
||||
For example, Spring's Redis support implements `FindByUsernameSessionRepository`.
|
||||
|
||||
[[api-enablespringhttpsession]]
|
||||
=== EnableSpringHttpSession
|
||||
|
||||
The `@EnableSpringHttpSession` annotation can be added to an `@Configuration` class to expose the `SessionRepositoryFilter` as a bean named "springSessionRepositoryFilter".
|
||||
In order to leverage the annotation, a single `SessionRepository` bean must be provided.
|
||||
For example:
|
||||
|
||||
[source,java,indent=0]
|
||||
----
|
||||
include::{docs-test-dir}docs/SpringHttpSessionConfig.java[tags=class]
|
||||
----
|
||||
|
||||
It is important to note that no infrastructure for session expirations is configured for you out of the box.
|
||||
This is because things like session expiration are highly implementation dependent.
|
||||
This means if you require cleaning up expired sessions, you are responsible for cleaning up the expired sessions.
|
||||
|
||||
[[api-redisoperationssessionrepository]]
|
||||
=== RedisOperationsSessionRepository
|
||||
|
||||
|
||||
@@ -15,13 +15,20 @@
|
||||
*/
|
||||
package docs;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
|
||||
import org.springframework.session.*;
|
||||
import org.springframework.session.data.redis.RedisOperationsSessionRepository;
|
||||
|
||||
import static org.fest.assertions.Assertions.assertThat;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
|
||||
import org.springframework.mock.web.MockServletContext;
|
||||
import org.springframework.session.ExpiringSession;
|
||||
import org.springframework.session.MapSessionRepository;
|
||||
import org.springframework.session.Session;
|
||||
import org.springframework.session.SessionRepository;
|
||||
import org.springframework.session.data.redis.RedisOperationsSessionRepository;
|
||||
import org.springframework.session.web.http.SessionRepositoryFilter;
|
||||
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
*/
|
||||
@@ -104,6 +111,20 @@ public class IndexDocTests {
|
||||
// end::new-mapsessionrepository[]
|
||||
}
|
||||
|
||||
@Test
|
||||
public void runSpringHttpSessionConfig() {
|
||||
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
|
||||
context.register(SpringHttpSessionConfig.class);
|
||||
context.setServletContext(new MockServletContext());
|
||||
context.refresh();
|
||||
|
||||
try {
|
||||
context.getBean(SessionRepositoryFilter.class);
|
||||
} finally {
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
||||
private static class User {
|
||||
private User(String username) {}
|
||||
}
|
||||
|
||||
32
docs/src/test/java/docs/SpringHttpSessionConfig.java
Normal file
32
docs/src/test/java/docs/SpringHttpSessionConfig.java
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package docs;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.session.MapSessionRepository;
|
||||
import org.springframework.session.config.annotation.web.http.EnableSpringHttpSession;
|
||||
|
||||
// tag::class[]
|
||||
@EnableSpringHttpSession
|
||||
@Configuration
|
||||
public class SpringHttpSessionConfig {
|
||||
@Bean
|
||||
public MapSessionRepository sessionRepository() {
|
||||
return new MapSessionRepository();
|
||||
}
|
||||
}
|
||||
// end::class[]
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.session.config.annotation.web.http;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.session.SessionRepository;
|
||||
import org.springframework.session.events.SessionCreatedEvent;
|
||||
import org.springframework.session.events.SessionDestroyedEvent;
|
||||
|
||||
/**
|
||||
* Add this annotation to an {@code @Configuration} class to expose the
|
||||
* SessionRepositoryFilter as a bean named "springSessionRepositoryFilter" and
|
||||
* backed by a user provided implementation of {@link SessionRepository}. In
|
||||
* order to leverage the annotation, a single {@link SessionRepository} bean
|
||||
* must be provided. For example:
|
||||
*
|
||||
* <pre>
|
||||
* <code>
|
||||
* {@literal @Configuration}
|
||||
* {@literal @EnableSpringHttpSession}
|
||||
* public class SpringHttpSessionConfig {
|
||||
*
|
||||
* {@literal @Bean}
|
||||
* public MapSessionRepository sessionRepository() {
|
||||
* return new MapSessionRepository();
|
||||
* }
|
||||
*
|
||||
* }
|
||||
* </code>
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* It is important to note that no infrastructure for session expirations is
|
||||
* configured for you out of the box. This is because things like session
|
||||
* expiration are highly implementation dependent. This means if you require
|
||||
* cleaning up expired sessions, you are responsible for cleaning up the expired
|
||||
* sessions.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The following is provided for you with the base configuration:
|
||||
* </p>
|
||||
*
|
||||
* <ul>
|
||||
* <li>SessionRepositoryFilter - is responsible for wrapping the
|
||||
* HttpServletRequest with an implementation of HttpSession that is backed by a
|
||||
* SessionRepository</li>
|
||||
* <li>SessionEventHttpSessionListenerAdapter - is responsible for translating
|
||||
* Spring Session events into HttpSessionEvent. In order for it to work, the
|
||||
* implementation of SessionRepository you provide must support
|
||||
* {@link SessionCreatedEvent} and {@link SessionDestroyedEvent}.</li>
|
||||
* <li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @since 1.0
|
||||
*/
|
||||
@Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
|
||||
@Target(value = { java.lang.annotation.ElementType.TYPE })
|
||||
@Documented
|
||||
@Import(SpringHttpSessionConfiguration.class)
|
||||
@Configuration
|
||||
public @interface EnableSpringHttpSession {
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.session.config.annotation.web.http;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpSessionListener;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.session.ExpiringSession;
|
||||
import org.springframework.session.SessionRepository;
|
||||
import org.springframework.session.events.SessionCreatedEvent;
|
||||
import org.springframework.session.events.SessionDestroyedEvent;
|
||||
import org.springframework.session.web.http.HttpSessionStrategy;
|
||||
import org.springframework.session.web.http.SessionEventHttpSessionListenerAdapter;
|
||||
import org.springframework.session.web.http.SessionRepositoryFilter;
|
||||
|
||||
/**
|
||||
* Configures the basics for setting up Spring Session in a web environment. In
|
||||
* order to use it, you must provide a {@link SessionRepository}. For example:
|
||||
*
|
||||
* <pre>
|
||||
* {@literal @Configuration}
|
||||
* {@literal @EnableSpringHttpSession}
|
||||
* public class SpringHttpSessionConfig {
|
||||
*
|
||||
* {@literal @Bean}
|
||||
* public MapSessionRepository sessionRepository() {
|
||||
* return new MapSessionRepository();
|
||||
* }
|
||||
*
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* It is important to note that no infrastructure for session expirations is
|
||||
* configured for you out of the box. This is because things like session
|
||||
* expiration are highly implementation dependent. This means if you require
|
||||
* cleaning up expired sessions, you are responsible for cleaning up the expired
|
||||
* sessions.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The following is provided for you with the base configuration:
|
||||
* </p>
|
||||
*
|
||||
* <ul>
|
||||
* <li>SessionRepositoryFilter - is responsible for wrapping the
|
||||
* HttpServletRequest with an implementation of HttpSession that is backed by a
|
||||
* SessionRepository</li>
|
||||
* <li>SessionEventHttpSessionListenerAdapter - is responsible for translating
|
||||
* Spring Session events into HttpSessionEvent. In order for it to work, the
|
||||
* implementation of SessionRepository you provide must support
|
||||
* {@link SessionCreatedEvent} and {@link SessionDestroyedEvent}.</li>
|
||||
* <li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @since 1.1
|
||||
*
|
||||
* @see EnableSpringHttpSession
|
||||
*/
|
||||
@Configuration
|
||||
@EnableScheduling
|
||||
public class SpringHttpSessionConfiguration {
|
||||
|
||||
private HttpSessionStrategy httpSessionStrategy;
|
||||
|
||||
private List<HttpSessionListener> httpSessionListeners = new ArrayList<HttpSessionListener>();
|
||||
|
||||
@Bean
|
||||
public SessionEventHttpSessionListenerAdapter sessionEventHttpSessionListenerAdapter() {
|
||||
return new SessionEventHttpSessionListenerAdapter(httpSessionListeners);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public <S extends ExpiringSession> SessionRepositoryFilter<? extends ExpiringSession> springSessionRepositoryFilter(SessionRepository<S> sessionRepository, ServletContext servletContext) {
|
||||
SessionRepositoryFilter<S> sessionRepositoryFilter = new SessionRepositoryFilter<S>(sessionRepository);
|
||||
sessionRepositoryFilter.setServletContext(servletContext);
|
||||
if(httpSessionStrategy != null) {
|
||||
sessionRepositoryFilter.setHttpSessionStrategy(httpSessionStrategy);
|
||||
}
|
||||
return sessionRepositoryFilter;
|
||||
}
|
||||
|
||||
@Autowired(required = false)
|
||||
public void setHttpSessionStrategy(HttpSessionStrategy httpSessionStrategy) {
|
||||
this.httpSessionStrategy = httpSessionStrategy;
|
||||
}
|
||||
|
||||
@Autowired(required = false)
|
||||
public void setHttpSessionListeners(List<HttpSessionListener> listeners) {
|
||||
this.httpSessionListeners = listeners;
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import java.lang.annotation.Target;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.session.config.annotation.web.http.EnableSpringHttpSession;
|
||||
|
||||
/**
|
||||
* Add this annotation to an {@code @Configuration} class to expose the
|
||||
@@ -29,6 +30,7 @@ import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
* backed by Redis. In order to leverage the annotation, a single {@link RedisConnectionFactory}
|
||||
* must be provided. For example:
|
||||
* <pre>
|
||||
* <code>
|
||||
* {@literal @Configuration}
|
||||
* {@literal @EnableRedisHttpSession}
|
||||
* public class RedisHttpSessionConfig {
|
||||
@@ -39,12 +41,14 @@ import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
* }
|
||||
*
|
||||
* }
|
||||
* </code>
|
||||
* </pre>
|
||||
*
|
||||
* More advanced configurations can extend {@link RedisHttpSessionConfiguration} instead.
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @since 1.0
|
||||
* @see EnableSpringHttpSession
|
||||
*/
|
||||
@Retention(value=java.lang.annotation.RetentionPolicy.RUNTIME)
|
||||
@Target(value={java.lang.annotation.ElementType.TYPE})
|
||||
|
||||
@@ -15,14 +15,9 @@
|
||||
*/
|
||||
package org.springframework.session.data.redis.config.annotation.web.http;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpSessionListener;
|
||||
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -42,13 +37,10 @@ import org.springframework.data.redis.listener.PatternTopic;
|
||||
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.session.ExpiringSession;
|
||||
import org.springframework.session.SessionRepository;
|
||||
import org.springframework.session.config.annotation.web.http.SpringHttpSessionConfiguration;
|
||||
import org.springframework.session.data.redis.RedisOperationsSessionRepository;
|
||||
import org.springframework.session.data.redis.config.ConfigureNotifyKeyspaceEventsAction;
|
||||
import org.springframework.session.data.redis.config.ConfigureRedisAction;
|
||||
import org.springframework.session.web.http.HttpSessionStrategy;
|
||||
import org.springframework.session.web.http.SessionEventHttpSessionListenerAdapter;
|
||||
import org.springframework.session.web.http.SessionRepositoryFilter;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -65,25 +57,16 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
@Configuration
|
||||
@EnableScheduling
|
||||
public class RedisHttpSessionConfiguration implements ImportAware, BeanClassLoaderAware {
|
||||
public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguration implements ImportAware, BeanClassLoaderAware {
|
||||
|
||||
private ClassLoader beanClassLoader;
|
||||
|
||||
private Integer maxInactiveIntervalInSeconds = 1800;
|
||||
|
||||
private HttpSessionStrategy httpSessionStrategy;
|
||||
|
||||
private ConfigureRedisAction configureRedisAction = new ConfigureNotifyKeyspaceEventsAction();
|
||||
|
||||
private List<HttpSessionListener> httpSessionListeners = new ArrayList<HttpSessionListener>();
|
||||
|
||||
private String redisNamespace = "";
|
||||
|
||||
@Bean
|
||||
public SessionEventHttpSessionListenerAdapter sessionEventHttpSessionListenerAdapter() {
|
||||
return new SessionEventHttpSessionListenerAdapter(httpSessionListeners);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RedisMessageListenerContainer redisMessageListenerContainer(
|
||||
RedisConnectionFactory connectionFactory, RedisOperationsSessionRepository messageListener) {
|
||||
@@ -118,16 +101,6 @@ public class RedisHttpSessionConfiguration implements ImportAware, BeanClassLoad
|
||||
return sessionRepository;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public <S extends ExpiringSession> SessionRepositoryFilter<? extends ExpiringSession> springSessionRepositoryFilter(SessionRepository<S> sessionRepository, ServletContext servletContext) {
|
||||
SessionRepositoryFilter<S> sessionRepositoryFilter = new SessionRepositoryFilter<S>(sessionRepository);
|
||||
sessionRepositoryFilter.setServletContext(servletContext);
|
||||
if(httpSessionStrategy != null) {
|
||||
sessionRepositoryFilter.setHttpSessionStrategy(httpSessionStrategy);
|
||||
}
|
||||
return sessionRepositoryFilter;
|
||||
}
|
||||
|
||||
public void setMaxInactiveIntervalInSeconds(int maxInactiveIntervalInSeconds) {
|
||||
this.maxInactiveIntervalInSeconds = maxInactiveIntervalInSeconds;
|
||||
}
|
||||
@@ -164,16 +137,6 @@ public class RedisHttpSessionConfiguration implements ImportAware, BeanClassLoad
|
||||
this.redisNamespace = enableAttrs.getString("redisNamespace");
|
||||
}
|
||||
|
||||
@Autowired(required = false)
|
||||
public void setHttpSessionStrategy(HttpSessionStrategy httpSessionStrategy) {
|
||||
this.httpSessionStrategy = httpSessionStrategy;
|
||||
}
|
||||
|
||||
@Autowired(required = false)
|
||||
public void setHttpSessionListeners(List<HttpSessionListener> listeners) {
|
||||
this.httpSessionListeners = listeners;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public InitializingBean enableRedisKeyspaceNotificationsInitializer(RedisConnectionFactory connectionFactory) {
|
||||
return new EnableRedisKeyspaceNotificationsInitializer(connectionFactory, configureRedisAction);
|
||||
|
||||
Reference in New Issue
Block a user