此版本仍在开发中,尚未被认为是稳定的。请使用最新的稳定版本 Spring Session 4.0.2spring-doc.cadn.net.cn

HttpSession 集成

Spring Session 提供了与 HttpSession 的透明集成。这意味着开发人员可以将 HttpSession 的实现切换为由 Spring Session 支撑的实现。spring-doc.cadn.net.cn

为什么选择 Spring Session 和HttpSession?

我们已经提到过,Spring Session 提供了与HttpSession的透明集成,但这种集成给我们带来了哪些好处呢?spring-doc.cadn.net.cn

HttpSession使用 Redis

使用 Spring Session 与 HttpSession 配合,需要在任何使用 HttpSession 的地方之前添加一个 Servlet 过滤器来启用。 您可以选择通过以下方式之一来启用此功能:spring-doc.cadn.net.cn

基于 Java 的 Redis 配置

此部分描述了如何通过使用基于Java的配置将Redis用作HttpSession的后端。spring-doc.cadn.net.cn

The HttpSession 示例 提供了如何通过使用 Java 配置来集成 Spring Session 和 HttpSession 的一个工作示例。 您可以在接下来的几节中阅读基本的集成步骤,但我们鼓励您在自己的应用程序中集成时跟随详细的 HttpSession 指南。

Spring Java 配置

在添加了所需的依赖项后,我们可以创建我们的Spring配置。 Spring 配置负责创建一个servlet过滤器,该过滤器用基于Spring Session 的实现替换掉 HttpSession 实现。 要实现这一点,请添加以下Spring 配置:spring-doc.cadn.net.cn

@Configuration(proxyBeanMethods = false)
@EnableRedisHttpSession (1)
public class Config {

	@Bean
	public LettuceConnectionFactory connectionFactory() {
		return new LettuceConnectionFactory(); (2)
	}

}
1 The @EnableRedisHttpSession注解创建一个名为springSessionRepositoryFilter的Spring Bean,该Bean实现了Filter。 过滤器负责将HttpSession实现替换为由Spring Session支持的实现。 在这种情况下,Spring Session通过Redis进行支持。
2 我们创建一个RedisConnectionFactory来将Spring Session与Redis服务器连接起来。 我们配置了连接信息,使其连接到本地主机的默认端口(6379)。 有关配置Spring Data Redis的更多信息,请参见参考文档

Java Servlet 容器初始化

我们的Spring Configuration创建了一个名为springSessionRepositoryFilter的Spring Bean,该Bean实现了FilterspringSessionRepositoryFilter Bean负责用一个由Spring Session支持的自定义实现来替换HttpSessionspring-doc.cadn.net.cn

为了使我们的Filter发挥魔力,Spring 需要加载我们的Config类。 最后,我们需要确保我们的 Servlet 容器(即 Tomcat)为每个请求使用我们的springSessionRepositoryFilter。 幸运的是,Spring Session 提供了一个名为AbstractHttpSessionApplicationInitializer的实用工具类来使这两步变得容易。 下面是一个示例:spring-doc.cadn.net.cn

src/main/java/sample/Initializer.java
public class Initializer extends AbstractHttpSessionApplicationInitializer { (1)

	public Initializer() {
		super(Config.class); (2)
	}

}
我们的类名(Initializer)无关紧要。重要的是我们继承了AbstractHttpSessionApplicationInitializer
1 第一步是扩展 AbstractHttpSessionApplicationInitializer。 这样做确保了名为 springSessionRepositoryFilter 的 Spring Bean 在每次请求时都会被注册到我们的Servlet容器中。
2 AbstractHttpSessionApplicationInitializer 也提供了一种机制确保Spring加载我们的Config

基于 XML 的 Redis 配置

此部分描述了如何通过基于XML的配置使用Redis来作为HttpSession的后备。spring-doc.cadn.net.cn

The HttpSession XML 示例 提供了如何使用 XML 配置将 Spring Session 和 HttpSession 进行集成的一个工作示例。 您可以在接下来的几节中阅读基本的整合步骤,但我们鼓励您在将此功能集成到您的应用程序时参考详细的 HttpSession XML 指南。

Spring XML 配置

在添加了所需的依赖项后,我们可以创建我们的Spring配置。 Spring 配置负责创建一个servlet过滤器,该过滤器用基于Spring Session 的实现替换掉 HttpSession 实现。 要实现这一点,请添加以下Spring 配置:spring-doc.cadn.net.cn

src/main/webapp/WEB-INF/spring/session.xml
(1)
<context:annotation-config/>
<bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"/>

(2)
<bean class="org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory"/>
1 我们使用<context:annotation-config/>RedisHttpSessionConfiguration的组合,因为Spring Session尚未提供XML命名空间支持(参见gh-104)。 这创建了一个名为springSessionRepositoryFilter的Spring Bean,实现了Filter接口。 过滤器负责将HttpSession实现替换为由Spring Session支持的方式。 在这个例子中,Spring Session由Redis支持。
2 我们创建一个RedisConnectionFactory来将Spring Session连接到Redis服务器。 我们配置了连接以连接到本地主机的默认端口(6379) 有关配置Spring Data Redis的更多信息,请参阅参考文档

XML Servlet 容器初始化

我们的Spring Configuration创建了一个名为springSessionRepositoryFilter的Spring Bean,该Bean实现了FilterspringSessionRepositoryFilter Bean负责用一个由Spring Session支持的自定义实现来替换HttpSessionspring-doc.cadn.net.cn

为了使我们的Filter能够发挥作用,我们需要指示Spring加载我们的session.xml配置。 我们可以通过以下配置来实现:spring-doc.cadn.net.cn

src/main/webapp/WEB-INF/web.xml
<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>
		/WEB-INF/spring/session.xml
	</param-value>
</context-param>
<listener>
	<listener-class>
		org.springframework.web.context.ContextLoaderListener
	</listener-class>
</listener>

The ContextLoaderListener 读取 contextConfigLocation 并加载我们的 session.xml 配置。spring-doc.cadn.net.cn

最后,我们需要确保我们的Servlet容器(即Tomcat)为每个请求使用我们的springSessionRepositoryFilter。 以下片段为我们执行这一步骤:spring-doc.cadn.net.cn

src/main/webapp/WEB-INF/web.xml
<filter>
	<filter-name>springSessionRepositoryFilter</filter-name>
	<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
	<filter-name>springSessionRepositoryFilter</filter-name>
	<url-pattern>/*</url-pattern>
	<dispatcher>REQUEST</dispatcher>
	<dispatcher>ERROR</dispatcher>
</filter-mapping>

The DelegatingFilterProxy 通过名称 springSessionRepositoryFilter 查找 Bean,并将其转换为 Filter。 每次调用 DelegatingFilterProxy 时,都会调用 springSessionRepositoryFilterspring-doc.cadn.net.cn

使用 Mongo 的 HttpSession

使用 Spring Session 与 HttpSession 是通过在任何使用 HttpSession 的内容之前添加一个 Servlet 过滤器来启用的。spring-doc.cadn.net.cn

此部分描述了如何使用Mongo作为HttpSession的后端,并通过Java基于配置的方式实现。spring-doc.cadn.net.cn

The HttpSession Mongo Sample 提供了如何使用 Java 配置将 Spring Session 和 HttpSession 集成的一个工作示例。 你可以在下面阅读基本的集成步骤,但是在为自己的应用程序进行集成时,我们鼓励你参考详细的 HttpSession 引导文档。

只需添加以下Spring配置即可:spring-doc.cadn.net.cn

@Configuration(proxyBeanMethods = false)
@EnableMongoHttpSession (1)
public class HttpSessionConfig {

	@Bean
	public JdkMongoSessionConverter jdkMongoSessionConverter() {
		return new JdkMongoSessionConverter(Duration.ofMinutes(30)); (2)
	}

}
1 The @EnableMongoHttpSession 注解创建一个名为 springSessionRepositoryFilter 的 Spring Bean,该 Bean 实现了 Filter。 这个过滤器将替换默认的 HttpSession 为带有 MongoDB 支持的 Bean。
2 配置会话超时为30分钟。

会话序列化机制

要将会话对象持久化到MongoDB中,我们需要提供序列化/反序列化的机制。spring-doc.cadn.net.cn

默认情况下,Spring Session MongoDB 将使用 JdkMongoSessionConverterspring-doc.cadn.net.cn

然而,您可以通过在您的 Boot 应用中添加以下代码来切换到 JacksonMongoSessionConverter:spring-doc.cadn.net.cn

@Bean
JacksonMongoSessionConverter mongoSessionConverter() {
    return new JacksonMongoSessionConverter();
}
JacksonMongoSessionConverter

此机制使用Jackson将会话对象序列化为/从JSON。spring-doc.cadn.net.cn

通过创建以下bean:spring-doc.cadn.net.cn

@Bean
JacksonMongoSessionConverter mongoSessionConverter() {
    return new JacksonMongoSessionConverter();
}

…您能够从默认(基于JDK的序列化)切换为使用Jackson。spring-doc.cadn.net.cn

如果您正在使用Spring Security进行集成(通过将会话存储在MongoDB中),此配置将会注册正确的白名单组件,使Spring Security能够正常工作。

如果您希望提供自定义的Jackson模块,可以通过显式注册模块来实现,示例如下:spring-doc.cadn.net.cn

Unresolved include directive in modules/ROOT/pages/http-session.adoc - include::example$spring-session-data-mongodb-dir/src/integration-test/java/org/springframework/session/data/mongo/integration/MongoRepositoryJacksonITest.java[]
JdkMongoSession转换器

JdkMongoSessionConverter 使用标准的 Java 序列化将会话属性映射持久化到 MongoDB 中,以二进制形式存储。 然而,像 id、访问时间等标准会话元素仍然以普通的 Mongo 对象形式写入,并且可以在不额外努力的情况下进行读取和查询。 JdkMongoSessionConverter 用于如果没有显式定义 AbstractMongoSessionConverter Bean 的情况。spring-doc.cadn.net.cn

也有一个接受SerializerDeserializer对象的构造函数,允许你传递自定义实现,特别是在你需要使用非默认类加载器时尤为重要。spring-doc.cadn.net.cn

HttpSession使用 JDBC

您可以使用 Spring Session 与 HttpSession,通过在任何使用 HttpSession 的地方之前添加一个 servlet 过滤器来实现。 您可以在以下任意一种方式中选择实现:spring-doc.cadn.net.cn

JDBC 基于 Java 的配置

此部分描述了如何在使用基于Java的配置时,使用关系型数据库来支持HttpSessionspring-doc.cadn.net.cn

The HttpSession JDBC Sample 提供了如何通过使用Java配置将 Spring Session 和 HttpSession 进行集成的一个工作示例。 您可以在接下来的几节中阅读基本步骤,但在自己应用程序中进行集成时,我们鼓励您参考详细的 HttpSession JDBC 指南。

Spring Java 配置

在添加了所需的依赖项后,我们可以创建我们的Spring配置。 Spring 配置负责创建一个servlet过滤器,该过滤器用基于Spring Session 的实现替换掉 HttpSession 实现。 要实现这一点,请添加以下Spring 配置:spring-doc.cadn.net.cn

@Configuration(proxyBeanMethods = false)
@EnableJdbcHttpSession (1)
public class Config {

	@Bean
	public EmbeddedDatabase dataSource() {
		return new EmbeddedDatabaseBuilder() (2)
			.setType(EmbeddedDatabaseType.H2)
			.addScript("org/springframework/session/jdbc/schema-h2.sql")
			.build();
	}

	@Bean
	public PlatformTransactionManager transactionManager(DataSource dataSource) {
		return new DataSourceTransactionManager(dataSource); (3)
	}

}
1 The @EnableJdbcHttpSession 注解创建一个名为 springSessionRepositoryFilter 的 Spring Bean。 该 Bean 实现了 Filter。 过滤器负责将 HttpSession 的实现替换为由 Spring Session 支持的实现。 在这个例子中,Spring Session 由关系数据库支持。
2 我们创建一个dataSource,将Spring Session连接到嵌入式的H2数据库实例。 我们通过使用Spring Session中包含的SQL脚本来配置H2数据库以创建数据库表。
3 我们创建一个transactionManager来管理之前配置好的dataSource的事务。

对于如何配置数据访问相关的设置的更多信息,请参阅 Spring 框架参考文档spring-doc.cadn.net.cn

Java Servlet 容器初始化

我们的Spring Configuration创建了一个名为springSessionRepositoryFilter的Spring Bean,该Bean实现了FilterspringSessionRepositoryFilter Bean负责用一个由Spring Session支持的自定义实现来替换HttpSessionspring-doc.cadn.net.cn

为了使我们的Filter发挥作用,Spring 需要加载我们的Config类。 最后,我们需要确保我们的Servlet容器(即Tomcat)为每个请求使用我们的springSessionRepositoryFilter。 幸运的是,Spring Session提供了一个名为AbstractHttpSessionApplicationInitializer的工具类来使这两步变得轻松。 以下示例展示了如何实现这一点:spring-doc.cadn.net.cn

src/main/java/sample/Initializer.java
public class Initializer extends AbstractHttpSessionApplicationInitializer { (1)

	public Initializer() {
		super(Config.class); (2)
	}

}
我们的类名(初始化器)并不重要。 重要的是我们继承了AbstractHttpSessionApplicationInitializer
1 第一步是扩展 AbstractHttpSessionApplicationInitializer。 这样做可以确保名为 springSessionRepositoryFilter 的 Spring bean 在每次请求时都注册到我们的 Servlet 容器中。
2 AbstractHttpSessionApplicationInitializer 也提供了一种机制确保Spring加载我们的Config

多个数据源

Spring Session 提供了 @SpringSessionDataSource 限定符,允许你显式声明应在 JdbcIndexedSessionRepository 中注入哪个 DataSource bean。 这在应用程序上下文中存在多个 DataSource bean 的情况下特别有用。spring-doc.cadn.net.cn

下面的例子展示了如何做到这一点:spring-doc.cadn.net.cn

Config.java
@EnableJdbcHttpSession
public class Config {

	@Bean
	@SpringSessionDataSource (1)
	public EmbeddedDatabase firstDataSource() {
		return new EmbeddedDatabaseBuilder()
				.setType(EmbeddedDatabaseType.H2).addScript("org/springframework/session/jdbc/schema-h2.sql").build();
	}

	@Bean
	public HikariDataSource secondDataSource() {
		// ...
	}
}
1 此限定符声明firstDataSource应由Spring Session使用。

基于 XML 的 JDBC 配置

此部分描述了如何在使用基于XML的配置时,使用关系数据库作为HttpSession的后端。spring-doc.cadn.net.cn

The HttpSession JDBC XML 样例 提供了如何通过使用 XML 配置将 Spring Session 和 HttpSession 进行集成的一个工作样本。 您可以在接下来的几节中阅读基本步骤,但在与自己的应用程序进行集成时,我们鼓励您参考详细的 HttpSession JDBC XML 指南。

Spring XML 配置

添加所需的依赖项后,我们可以创建我们的 Spring 配置。 Spring 配置负责创建一个 servlet 过滤器,该过滤器用基于 Spring Session 的实现替换 HttpSession 实现。 以下示例显示了如何添加以下 Spring 配置:spring-doc.cadn.net.cn

src/main/webapp/WEB-INF/spring/session.xml
(1)
<context:annotation-config/>
<bean class="org.springframework.session.jdbc.config.annotation.web.http.JdbcHttpSessionConfiguration"/>

(2)
<jdbc:embedded-database id="dataSource" database-name="testdb" type="H2">
	<jdbc:script location="classpath:org/springframework/session/jdbc/schema-h2.sql"/>
</jdbc:embedded-database>

(3)
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<constructor-arg ref="dataSource"/>
</bean>
1 我们使用<context:annotation-config/>JdbcHttpSessionConfiguration的组合,因为Spring Session尚未提供XML命名空间支持(参见gh-104)。 这会创建一个名为springSessionRepositoryFilter的Spring bean。 该bean实现了Filter。 过滤器负责将HttpSession实现替换为由Spring Session支持的实现。 在这种情况下,Spring Session是由关系型数据库支持的。
2 我们创建一个dataSource,将Spring Session连接到嵌入式的H2数据库实例。 我们通过使用Spring Session中包含的SQL脚本来配置H2数据库以创建数据库表。
3 我们创建一个transactionManager来管理之前配置好的dataSource的事务。

对于如何配置数据访问相关的设置的更多信息,请参阅 Spring 框架参考文档spring-doc.cadn.net.cn

XML Servlet 容器初始化

我们的Spring Configuration创建了一个名为springSessionRepositoryFilter的Spring Bean,该Bean实现了FilterspringSessionRepositoryFilter Bean负责用一个由Spring Session支持的自定义实现来替换HttpSessionspring-doc.cadn.net.cn

为了使我们的Filter能够发挥作用,我们需要指示Spring加载我们的session.xml配置。 我们通过以下配置来实现这一点:spring-doc.cadn.net.cn

src/main/webapp/WEB-INF/web.xml
<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>
		/WEB-INF/spring/session.xml
	</param-value>
</context-param>
<listener>
	<listener-class>
		org.springframework.web.context.ContextLoaderListener
	</listener-class>
</listener>

The ContextLoaderListener 读取 contextConfigLocation 并加载我们的 session.xml 配置文件。spring-doc.cadn.net.cn

最后,我们需要确保我们的Servlet容器(即Tomcat)为每个请求使用我们的springSessionRepositoryFilter。 以下片段为我们执行这一步骤:spring-doc.cadn.net.cn

src/main/webapp/WEB-INF/web.xml
<filter>
	<filter-name>springSessionRepositoryFilter</filter-name>
	<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
	<filter-name>springSessionRepositoryFilter</filter-name>
	<url-pattern>/*</url-pattern>
	<dispatcher>REQUEST</dispatcher>
	<dispatcher>ERROR</dispatcher>
</filter-mapping>

The DelegatingFilterProxy 会查找名为 springSessionRepositoryFilter 的 Bean,并将其转换为 Filter 类型。 对于每次调用 DelegatingFilterProxy 的请求,都会触发 springSessionRepositoryFilter 的调用。spring-doc.cadn.net.cn

基于 Spring Boot 的 JDBC 配置

此部分描述了如何在使用 Spring Boot 时,使用关系型数据库来支持 HttpSessionspring-doc.cadn.net.cn

The HttpSession JDBC Spring Boot Sample 提供了一个如何使用 Spring Boot 将 Spring Session 与 HttpSession 集成的可运行示例。 您可以在接下来的几个部分中阅读集成的基本步骤,但我们鼓励您在将此功能整合到您自己的应用程序时跟随详细的 HttpSession JDBC Spring Boot 指南。

Spring Boot 配置

在添加了所需的依赖项后,我们可以创建我们的Spring Boot配置。 得益于一流的自动配置支持,只需添加依赖项,Spring Boot 就会为我们设置基于关系数据库的 Spring Session。spring-doc.cadn.net.cn

如果类路径上仅存在一个 Spring Session 模块,Spring Boot 将会自动使用该存储实现。 如果有多个实现,则必须选择您希望用于存储会话的 StoreType,如上方所示。spring-doc.cadn.net.cn

在幕后,Spring Boot 应用了等同于手动添加 @EnableSessionSaveFilter 注解的配置。 这创建了一个名为 @EnableJdbcHttpSession 的 Spring 原型 bean。该 bean 实现了 springSessionRepositoryFilter 接口。 过滤器负责将 Filter 实现替换为由 Spring Session 支撑的实现。spring-doc.cadn.net.cn

您可以进一步自定义,可以使用application.properties。 以下示例展示了如何做到这一点:spring-doc.cadn.net.cn

src/main/resources/application.properties
server.servlet.session.timeout= # Session timeout. If a duration suffix is not specified, seconds are used.
spring.session.jdbc.initialize-schema=embedded # Database schema initialization mode.
spring.session.jdbc.schema=classpath:org/springframework/session/jdbc/schema-@@platform@@.sql # Path to the SQL file to use to initialize the database schema.
spring.session.jdbc.table-name=SPRING_SESSION # Name of the database table used to store sessions.

对于更多信息,请参阅Spring Session部分的Spring Boot 文档。spring-doc.cadn.net.cn

配置DataSource

Spring Boot 自动创建了一个 DataSource,将 Spring Session 连接到嵌入式的 H2 数据库实例。 在生产环境中,您需要更新配置以指向您的关系数据库。 例如,您可以在 application.properties 中包含以下内容:spring-doc.cadn.net.cn

src/main/resources/application.properties
spring.datasource.url= # JDBC URL of the database.
spring.datasource.username= # Login username of the database.
spring.datasource.password= # Login password of the database.

更多详细信息,请参阅Spring Boot 文档中的配置数据源部分。spring-doc.cadn.net.cn

Servlet 容器初始化

我们的 Spring Boot 配置 创建了一个名为 springSessionRepositoryFilter 的 Spring bean,它实现了 FilterspringSessionRepositoryFilter bean 负责用一个由 Spring Session 支撑的自定义实现来替换 HttpSessionspring-doc.cadn.net.cn

为了使我们的Filter发挥魔力,Spring 需要加载我们的Config类。 最后,我们需要确保我们的 servlet 容器(即 Tomcat)为每个请求使用我们的springSessionRepositoryFilter。 幸运的是,Spring Boot 会为我们处理这两个步骤。spring-doc.cadn.net.cn

HttpSession 与 Hazelcast

使用 Spring Session 与 HttpSession 是通过在任何使用 HttpSession 的内容之前添加一个 Servlet 过滤器来启用的。spring-doc.cadn.net.cn

此部分描述了如何使用 Hazelcast 来为 HttpSession 提供支持,并通过基于 Java 的配置来实现。spring-doc.cadn.net.cn

The Hazelcast Spring Sample 提供了一个如何使用 Java 配置将 Spring Session 和 HttpSession 进行集成的工作样本。 您可以在接下来的几段中阅读基本的整合步骤,但当我们自己应用时我们鼓励您参考详细的 Hazelcast Spring 指南。

Spring 配置

在添加了所需的依赖项后,我们可以创建我们的Spring配置。 Spring 配置负责创建一个servlet过滤器,该过滤器用基于Spring Session 的实现替换掉 HttpSession 实现。 要实现这一点,请添加以下Spring 配置:spring-doc.cadn.net.cn

@EnableHazelcastHttpSession (1)
@Configuration
public class HazelcastHttpSessionConfig {

	@Bean
	public HazelcastInstance hazelcastInstance() {
		Config config = new Config();
		AttributeConfig attributeConfig = new AttributeConfig()
			.setName(HazelcastIndexedSessionRepository.PRINCIPAL_NAME_ATTRIBUTE)
			.setExtractorClassName(PrincipalNameExtractor.class.getName());
		config.getMapConfig(HazelcastIndexedSessionRepository.DEFAULT_SESSION_MAP_NAME) (2)
			.addAttributeConfig(attributeConfig)
			.addIndexConfig(
					new IndexConfig(IndexType.HASH, HazelcastIndexedSessionRepository.PRINCIPAL_NAME_ATTRIBUTE));
		SerializerConfig serializerConfig = new SerializerConfig();
		serializerConfig.setImplementation(new HazelcastSessionSerializer()).setTypeClass(MapSession.class);
		config.getSerializationConfig().addSerializerConfig(serializerConfig); (3)
		return Hazelcast.newHazelcastInstance(config); (4)
	}

}
1 @EnableHazelcastHttpSession 注解创建一个名为 springSessionRepositoryFilter 的 Spring 颗粒(bean),实现 Filter。 该过滤器负责将 HttpSession 实现替换为由 Spring Session 支持的实现。 在这个例子中,Spring Session 由 Hazelcast 支持。
2 要支持按主体名称索引检索会话,需要注册一个合适的ValueExtractor。 Spring Session为此提供了PrincipalNameExtractor
3 为了高效地序列化MapSession对象,需要注册HazelcastSessionSerializer。如果不设置此配置,Hazelcast 将使用原生Java序列化来序列化会话。
4 我们创建一个HazelcastInstance来将Spring Session与Hazelcast连接起来。 默认情况下,应用程序启动并连接到嵌入式Hazelcast实例。 有关配置Hazelcast的更多信息,请参阅参考文档
如果希望使用HazelcastSessionSerializer,则需要在所有Hazelcast集群成员启动之前进行配置。 在Hazelcast集群中,所有成员都应使用相同的会话序列化方法。另外,如果使用了Hazelcast客户端/服务器架构,则成员和客户端都必须使用相同的序列化方法。可以通过ClientConfig注册序列化器,并使用与成员相同的SerializerConfiguration

Servlet 容器初始化

我们的Spring 配置创建了一个名为springSessionRepositoryFilter的 Spring bean,该bean实现了FilterspringSessionRepositoryFilter bean负责用一个由 Spring Session 支撑的自定义实现来替换HttpSessionspring-doc.cadn.net.cn

为了使我们的Filter发挥魔力,Spring 需要加载我们的SessionConfig类。 由于我们已经通过使用SecurityInitializer类来加载应用程序的 Spring 配置,因此我们可以将SessionConfig类添加到其中。 以下列表显示了如何实现这一点:spring-doc.cadn.net.cn

src/main/java/sample/SecurityInitializer.java
public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer {

	public SecurityInitializer() {
		super(SecurityConfig.class, SessionConfig.class);
	}

}

最后,我们需要确保我们的Servlet容器(即Tomcat)为每个请求使用我们的springSessionRepositoryFilter。 这非常重要的是,Spring Session的springSessionRepositoryFilter必须在Spring Security的springSecurityFilterChain之前被调用。 这样做可以确保Spring Security使用的HttpSession是由Spring Session支持的。 幸运的是,Spring Session提供了一个名为AbstractHttpSessionApplicationInitializer的工具类,使得这一操作变得简单。 以下示例展示了如何实现这一点:spring-doc.cadn.net.cn

src/main/java/sample/Initializer.java
public class Initializer extends AbstractHttpSessionApplicationInitializer {

}
我们的类名(Initializer)无关紧要。重要的是我们继承了AbstractHttpSessionApplicationInitializer

通过扩展AbstractHttpSessionApplicationInitializer,我们确保名为springSessionRepositoryFilter的Spring bean在每次请求中都会被注册到我们的Servlet容器中,在Spring Security的springSecurityFilterChain之前。spring-doc.cadn.net.cn

如何HttpSession集成工作

幸运的是,两个HttpSessionHttpServletRequest(获取HttpSession的API)都是接口。 这意味着我们可以为每个这些API提供自己的实现。spring-doc.cadn.net.cn

这一部分描述了 Spring Session 如何提供与 HttpSession 的透明集成。我们提供此内容以便您了解幕后发生了什么。这种功能已经集成了,因此您无需自行实现这些逻辑。

首先,我们创建一个自定义的HttpServletRequest,它返回一个自定义实现的HttpSession。 它的大致样子如下所示:spring-doc.cadn.net.cn

public class SessionRepositoryRequestWrapper extends HttpServletRequestWrapper {

	public SessionRepositoryRequestWrapper(HttpServletRequest original) {
		super(original);
	}

	public HttpSession getSession() {
		return getSession(true);
	}

	public HttpSession getSession(boolean createNew) {
		// create an HttpSession implementation from Spring Session
	}

	// ... other methods delegate to the original HttpServletRequest ...
}

任何返回HttpSession的方法都被覆盖了。 所有其他方法均由HttpServletRequestWrapper实现,并委托给原始的HttpServletRequest实现。spring-doc.cadn.net.cn

我们用一个名为SessionRepositoryFilter的servletFilter替换掉了HttpServletRequest实现。 以下伪代码展示了其实现方式:spring-doc.cadn.net.cn

public class SessionRepositoryFilter implements Filter {

	public doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
		HttpServletRequest httpRequest = (HttpServletRequest) request;
		SessionRepositoryRequestWrapper customRequest =
			new SessionRepositoryRequestWrapper(httpRequest);

		chain.doFilter(customRequest, response, chain);
	}

	// ...
}

通过向FilterChain传递自定义的HttpServletRequest实现,我们确保在我们的Filter之后调用的所有内容都使用了自定义的HttpSession实现。 这突显了为什么Spring Session的SessionRepositoryFilter需要放在任何与HttpSession交互的内容之前的重要性。spring-doc.cadn.net.cn

HttpSession和 RESTful API

Spring Session 可以与 RESTful API 一起工作,通过在头部提供会话来实现。spring-doc.cadn.net.cn

REST Sample 提供了一个使用 Spring Session 在 REST 应用程序中支持基于头部认证的工作示例。 您可以遵循接下来几节中描述的基本集成步骤,但在将 Spring Session 集成到您自己的应用程序时,我们建议您参考详细的 REST 指南。

Spring 配置

在添加了所需的依赖项后,我们可以创建我们的Spring配置。 Spring 配置负责创建一个servlet过滤器,该过滤器用基于Spring Session 的实现替换掉 HttpSession 实现。 要实现这一点,请添加以下Spring 配置:spring-doc.cadn.net.cn

@Configuration
@EnableRedisHttpSession (1)
public class HttpSessionConfig {

	@Bean
	public LettuceConnectionFactory connectionFactory() {
		return new LettuceConnectionFactory(); (2)
	}

	@Bean
	public HttpSessionIdResolver httpSessionIdResolver() {
		return HeaderHttpSessionIdResolver.xAuthToken(); (3)
	}

}
1 The @EnableRedisHttpSession 注解创建一个名为 springSessionRepositoryFilter 的 Spring bean,该 bean 实现了 Filter。 该过滤器负责将 HttpSession 实现替换为由 Spring Session 支持的实现。 在此情况下,Spring Session 由 Redis 支持。
2 我们创建一个RedisConnectionFactory来将Spring Session与Redis服务器连接起来。 我们配置了连接信息,使其连接到本地主机的默认端口(6379)。 有关配置Spring Data Redis的更多信息,请参见参考文档
3 我们自定义了Spring Session的HttpSession集成,使其通过HTTP标头来传递当前会话信息而不是使用cookie。

Servlet 容器初始化

我们的Spring Configuration创建了一个名为springSessionRepositoryFilter的Spring Bean,该Bean实现了FilterspringSessionRepositoryFilter Bean负责用一个由Spring Session支持的自定义实现来替换HttpSessionspring-doc.cadn.net.cn

为了使我们的Filter能够发挥作用,Spring需要加载我们的Config类。 我们通过Spring的MvcInitializer提供配置,如下例所示:spring-doc.cadn.net.cn

src/main/java/sample/mvc/MvcInitializer.java
@Override
protected Class<?>[] getRootConfigClasses() {
	return new Class[] { SecurityConfig.class, HttpSessionConfig.class };
}

最后,我们需要确保我们的Servlet容器(即Tomcat)为每个请求使用我们的springSessionRepositoryFilter。 幸运的是,Spring Session提供了一个名为AbstractHttpSessionApplicationInitializer的实用类,使得这一操作变得简单。要做到这一点,请使用默认构造函数扩展该类,如以下示例所示:spring-doc.cadn.net.cn

src/main/java/sample/Initializer.java
public class Initializer extends AbstractHttpSessionApplicationInitializer {

}
我们的类名(Initializer)无关紧要。重要的是我们继承了AbstractHttpSessionApplicationInitializer

使用HttpSessionListener

Spring Session 支持 HttpSessionListener,通过将 SessionDestroyedEventSessionCreatedEvent 转换为 HttpSessionEvent 实现。这通过声明 SessionEventHttpSessionListenerAdapter 来完成。 要使用此支持,您需要:
spring-doc.cadn.net.cn

如果使用带有enableIndexingAndEvents设置为true@EnableRedisHttpSession(enableIndexingAndEvents = true)的Redis支持,您只需将每个HttpSessionListener注册为一个bean。 例如,假设您希望支持Spring Security的并发控制并需要使用HttpSessionEventPublisher。在这种情况下,可以将HttpSessionEventPublisher作为一个bean添加。 在Java配置中,这可能会如下所示:spring-doc.cadn.net.cn

@Configuration
@EnableRedisHttpSession
public class RedisHttpSessionConfig {

	@Bean
	public HttpSessionEventPublisher httpSessionEventPublisher() {
		return new HttpSessionEventPublisher();
	}

	// ...

}

在XML配置中,这可能如下所示:spring-doc.cadn.net.cn

<bean class="org.springframework.security.web.session.HttpSessionEventPublisher"/>