对于最新的稳定版本,请使用 Spring Session 3.3.1

对于最新的稳定版本,请使用 Spring Session 3.3.1

Spring Session 提供与 的透明集成。 这意味着开发人员可以使用 Spring Session 支持的实现来切换实现。HttpSessionHttpSession

为什么选择Spring Session和?HttpSession

我们已经提到过 Spring Session 提供了透明的集成,但是我们从中得到了什么好处?HttpSession

  • 集群会话:Spring Session 使支持集群会话变得简单,而不必绑定到特定于应用程序容器的解决方案。

  • RESTful API:Spring Session 允许在标头中提供会话 ID 与 RESTful API 一起使用

HttpSession使用 Redis

通过在使用 . 您可以通过以下任一方式选择启用此功能:HttpSessionHttpSession

基于 Java 的 Redis 配置

本节介绍如何使用 Redis 通过基于 Java 的配置进行后退。HttpSession

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

Spring Java 配置

添加所需的依赖项后,我们可以创建 Spring 配置。 Spring 配置负责创建一个 servlet 过滤器,该过滤器将实现替换为 Spring Session 支持的实现。 为此,请添加以下 Spring 配置:HttpSession

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

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

}
1 注解创建一个 Spring Bean,其名称为实现 。 过滤器负责替换 Spring Session 支持的实现。 在这种情况下,Spring Session 由 Redis 提供支持。@EnableRedisHttpSessionspringSessionRepositoryFilterFilterHttpSession
2 我们创建一个将 Spring Session 连接到 Redis 服务器。 我们将连接配置为连接到默认端口 (6379) 上的 localhost。 有关配置 Spring Data Redis 的更多信息,请参阅参考文档RedisConnectionFactory

Java Servlet 容器初始化

我们的 Spring Configuration 创建了一个名为 的 Spring Bean,用于实现 . Bean 负责用 Spring Session 支持的自定义实现替换 bean。springSessionRepositoryFilterFilterspringSessionRepositoryFilterHttpSession

为了让我们发挥它的魔力,Spring 需要加载我们的类。 最后,我们需要确保我们的 Servlet 容器(即 Tomcat)对每个请求都使用我们的容器。 幸运的是,Spring Session 提供了一个名为 Utility 类,使这两个步骤变得简单。 下面显示了一个示例:FilterConfigspringSessionRepositoryFilterAbstractHttpSessionApplicationInitializer

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

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

}
我们类 () 的名称无关紧要。重要的是我们扩展.InitializerAbstractHttpSessionApplicationInitializer
1 第一步是扩展 . 这样做可以确保每个请求都向 Servlet 容器中注册名为 Spring Bean。AbstractHttpSessionApplicationInitializerspringSessionRepositoryFilter
2 AbstractHttpSessionApplicationInitializer还提供了一种机制来确保 Spring 加载我们的 .Config

基于 Redis XML 的配置

本节介绍如何使用 Redis 通过基于 XML 的配置进行后退。HttpSession

HttpSession XML 示例提供了如何集成 Spring Session 和使用 XML 配置的工作示例。 您可以阅读接下来几节中的集成基本步骤,但我们建议您在与自己的应用程序集成时遵循详细的 HttpSession XML 指南。HttpSession

Spring XML 配置

添加所需的依赖项后,我们可以创建 Spring 配置。 Spring 配置负责创建一个 servlet 过滤器,该过滤器将实现替换为 Spring Session 支持的实现。 为此,请添加以下 Spring 配置:HttpSession

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 我们使用 和 的组合,因为 Spring Session 还没有提供 XML 命名空间支持(参见 gh-104)。 这将创建一个 Spring Bean,其名称为该实现。 过滤器负责替换 Spring Session 支持的实现。 在这种情况下,Spring Session 由 Redis 提供支持。<context:annotation-config/>RedisHttpSessionConfigurationspringSessionRepositoryFilterFilterHttpSession
2 我们创建一个将 Spring Session 连接到 Redis 服务器。 我们将连接配置为在默认端口 (6379) 上连接到 localhost 有关配置 Spring Data Redis 的更多信息,请参阅参考文档RedisConnectionFactory

XML Servlet 容器初始化

我们的 Spring Configuration 创建了一个名为 的 Spring Bean,用于实现 . Bean 负责用 Spring Session 支持的自定义实现替换 bean。springSessionRepositoryFilterFilterspringSessionRepositoryFilterHttpSession

为了让我们发挥它的魔力,我们需要指示 Spring 加载我们的配置。 我们可以通过以下配置来做到这一点:Filtersession.xml

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>

ContextLoaderListener 读取 contextConfigLocation 并选取我们的session.xml配置。

最后,我们需要确保我们的 Servlet 容器(即 Tomcat)对每个请求都使用我们的容器。 以下代码片段为我们执行最后一步:springSessionRepositoryFilter

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>

DelegatingFilterProxy 按 of 的名称查找 Bean 并将其强制转换为 . 对于调用的每个请求,都会调用 。springSessionRepositoryFilterFilterDelegatingFilterProxyspringSessionRepositoryFilter

使用 Mongo 的 HttpSession

通过在使用 .HttpSessionHttpSession

本节介绍如何使用 Mongo 支持使用基于 Java 的配置。HttpSession

HttpSession Mongo 示例提供了有关如何集成 Spring Session 和使用 Java 配置的工作示例。 您可以阅读下面的集成基本步骤,但建议您在与自己的应用程序集成时遵循详细的 HttpSession 指南。HttpSession

您所要做的就是添加以下 Spring 配置:

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

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

}
1 注解创建一个 Spring Bean,其名称为实现 Filter。 此过滤器将默认过滤器替换为 MongoDB 支持的 bean。@EnableMongoHttpSessionspringSessionRepositoryFilterHttpSession
2 将会话超时配置为 30 分钟。

会话序列化机制

为了能够在MongoDB中持久化会话对象,我们需要提供序列化/反序列化机制。

默认情况下,Spring Session MongoDB 将使用 .JdkMongoSessionConverter

但是,只需将以下代码添加到启动应用即可切换到:JacksonMongoSessionConverter

@Bean
JacksonMongoSessionConverter mongoSessionConverter() {
    return new JacksonMongoSessionConverter();
}
杰克逊MongoSessionConverter

此机制使用 Jackson 将会话对象序列化为 JSON。

通过创建以下 bean:

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

…​您可以从默认(基于 JDK 的序列化)切换到使用 Jackson。

如果您要与 Spring Security 集成(通过将会话存储在 MongoDB 中),则此配置将 注册适当的白名单组件,以便 Spring Security 正常工作。

如果要提供自定义 Jackson 模块,可以通过显式注册模块来实现,如下所示:

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[]
JdkMongoSessionConverter

JdkMongoSessionConverter使用标准 Java 序列化以二进制形式持久化映射到 MongoDB 的会话属性。 但是,id、访问时间等标准会话元素仍被写为普通的 Mongo 对象,无需额外工作即可读取和查询。 如果尚未定义显式 Bean,则使用。JdkMongoSessionConverterAbstractMongoSessionConverter

还有一个构造函数 和 对象,允许您传递自定义实现,这在您想要使用非默认类加载器时尤为重要。SerializerDeserializer

HttpSession 示例提供了如何集成 Spring Session 和使用 Java 配置的工作示例。 您可以阅读接下来几节中的集成基本步骤,但我们鼓励您在与自己的应用程序集成时遵循详细的 HttpSession 指南。HttpSession
1 注解创建一个 Spring Bean,其名称为实现 。 过滤器负责替换 Spring Session 支持的实现。 在这种情况下,Spring Session 由 Redis 提供支持。@EnableRedisHttpSessionspringSessionRepositoryFilterFilterHttpSession
2 我们创建一个将 Spring Session 连接到 Redis 服务器。 我们将连接配置为连接到默认端口 (6379) 上的 localhost。 有关配置 Spring Data Redis 的更多信息,请参阅参考文档RedisConnectionFactory
我们类 () 的名称无关紧要。重要的是我们扩展.InitializerAbstractHttpSessionApplicationInitializer
1 第一步是扩展 . 这样做可以确保每个请求都向 Servlet 容器中注册名为 Spring Bean。AbstractHttpSessionApplicationInitializerspringSessionRepositoryFilter
2 AbstractHttpSessionApplicationInitializer还提供了一种机制来确保 Spring 加载我们的 .Config
HttpSession XML 示例提供了如何集成 Spring Session 和使用 XML 配置的工作示例。 您可以阅读接下来几节中的集成基本步骤,但我们建议您在与自己的应用程序集成时遵循详细的 HttpSession XML 指南。HttpSession
1 我们使用 和 的组合,因为 Spring Session 还没有提供 XML 命名空间支持(参见 gh-104)。 这将创建一个 Spring Bean,其名称为该实现。 过滤器负责替换 Spring Session 支持的实现。 在这种情况下,Spring Session 由 Redis 提供支持。<context:annotation-config/>RedisHttpSessionConfigurationspringSessionRepositoryFilterFilterHttpSession
2 我们创建一个将 Spring Session 连接到 Redis 服务器。 我们将连接配置为在默认端口 (6379) 上连接到 localhost 有关配置 Spring Data Redis 的更多信息,请参阅参考文档RedisConnectionFactory
HttpSession Mongo 示例提供了有关如何集成 Spring Session 和使用 Java 配置的工作示例。 您可以阅读下面的集成基本步骤,但建议您在与自己的应用程序集成时遵循详细的 HttpSession 指南。HttpSession
1 注解创建一个 Spring Bean,其名称为实现 Filter。 此过滤器将默认过滤器替换为 MongoDB 支持的 bean。@EnableMongoHttpSessionspringSessionRepositoryFilterHttpSession
2 将会话超时配置为 30 分钟。
如果您要与 Spring Security 集成(通过将会话存储在 MongoDB 中),则此配置将 注册适当的白名单组件,以便 Spring Security 正常工作。

HttpSession使用 JDBC

您可以通过在使用 . 您可以选择以下任一方式执行此操作:HttpSessionHttpSession

基于 JDBC Java 的配置

本节介绍在使用基于 Java 的配置时如何使用关系数据库进行备份。HttpSession

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

Spring Java 配置

添加所需的依赖项后,我们可以创建 Spring 配置。 Spring 配置负责创建一个 Servlet 过滤器,该过滤器将实现替换为 Spring Session 支持的实现。 为此,请添加以下 Spring 配置:HttpSession

@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 注释将创建名称为 的 Spring Bean。 该 bean 实现 . 过滤器负责替换 Spring Session 支持的实现。 在这种情况下,Spring Session 由关系数据库提供支持。@EnableJdbcHttpSessionspringSessionRepositoryFilterFilterHttpSession
2 我们创建一个将 Spring Session 连接到 H2 数据库的嵌入式实例。 我们将 H2 数据库配置为使用 Spring Session 中包含的 SQL 脚本创建数据库表。dataSource
3 我们创建一个来管理先前配置的事务。transactionManagerdataSource

有关如何配置数据访问相关问题的其他信息,请参阅 Spring Framework 参考文档

Java Servlet 容器初始化

我们的 Spring Configuration 创建了一个名为 的 Spring Bean,用于实现 . Bean 负责用 Spring Session 支持的自定义实现替换 bean。springSessionRepositoryFilterFilterspringSessionRepositoryFilterHttpSession

为了让我们发挥它的魔力,Spring 需要加载我们的类。 最后,我们需要确保我们的 Servlet 容器(即 Tomcat)对每个请求都使用我们的容器。 幸运的是,Spring Session 提供了一个名为 Utility 类,使这两个步骤变得简单。 以下示例演示如何执行此操作:FilterConfigspringSessionRepositoryFilterAbstractHttpSessionApplicationInitializer

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

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

}
我们类的名称(初始值设定项)无关紧要。 重要的是我们扩展.AbstractHttpSessionApplicationInitializer
1 第一步是扩展 . 这样做可以确保每个请求都向 Servlet 容器注册名为 Spring bean。AbstractHttpSessionApplicationInitializerspringSessionRepositoryFilter
2 AbstractHttpSessionApplicationInitializer还提供了一种机制来确保 Spring 加载我们的 .Config

多个数据源

Spring Session 提供了限定符,允许您显式声明应该在 中注入哪个 Bean。 这在应用程序上下文中存在多个 Bean 的场景中特别有用。@SpringSessionDataSourceDataSourceJdbcIndexedSessionRepositoryDataSource

以下示例演示如何执行此操作:

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 此限定符声明 springSession 将使用 firstDataSource。

基于 JDBC XML 的配置

本节介绍在使用基于 XML 的配置时如何使用关系数据库进行备份。HttpSession

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

Spring XML 配置

添加所需的依赖项后,我们可以创建 Spring 配置。 Spring 配置负责创建一个 servlet 过滤器,该过滤器将实现替换为 Spring Session 支持的实现。 以下列表显示了如何添加以下 Spring 配置:HttpSession

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 我们使用 和 的组合,因为 Spring Session 还没有提供 XML 命名空间支持(参见 gh-104)。 这将创建一个名为 的 Spring Bean。 该 bean 实现 . 过滤器负责替换 Spring Session 支持的实现。 在这种情况下,Spring Session 由关系数据库提供支持。<context:annotation-config/>JdbcHttpSessionConfigurationspringSessionRepositoryFilterFilterHttpSession
2 我们创建一个将 Spring Session 连接到 H2 数据库的嵌入式实例。 我们将 H2 数据库配置为使用 Spring Session 中包含的 SQL 脚本创建数据库表。dataSource
3 我们创建一个来管理先前配置的事务。transactionManagerdataSource

有关如何配置与数据访问相关的问题的其他信息,请参阅 Spring Framework 参考文档

XML Servlet 容器初始化

我们的 Spring Configuration 创建了一个名为 的 Spring Bean,用于实现 . Bean 负责用 Spring Session 支持的自定义实现替换 bean。springSessionRepositoryFilterFilterspringSessionRepositoryFilterHttpSession

为了让我们发挥它的魔力,我们需要指示 Spring 加载我们的配置。 我们使用以下配置来执行此操作:Filtersession.xml

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>

ContextLoaderListener 读取并获取我们的session.xml配置。contextConfigLocation

最后,我们需要确保我们的 Servlet 容器(即 Tomcat)对每个请求都使用我们的容器。 以下代码片段为我们执行最后一步:springSessionRepositoryFilter

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>

DelegatingFilterProxy 查找名为 的 Bean 并将其强制转换为 . 对于调用的每个请求,都会调用 。springSessionRepositoryFilterFilterDelegatingFilterProxyspringSessionRepositoryFilter

基于 JDBC Spring Boot 的配置

本节介绍如何在使用 Spring Boot 时使用关系数据库进行备份。HttpSession

HttpSession JDBC Spring Boot 示例提供了如何集成 Spring Session 和使用 Spring Boot 的工作示例。 您可以阅读接下来几节中的集成基本步骤,但我们建议您在与自己的应用程序集成时遵循详细的 HttpSession JDBC Spring Boot 指南。HttpSession

Spring Boot 配置

添加所需的依赖项后,我们可以创建 Spring Boot 配置。 由于一流的自动配置支持,设置由关系数据库支持的 Spring Session 就像将单个配置属性添加到 . 以下列表显示了如何执行此操作:application.properties

src/main/resources/application.properties
spring.session.store-type=jdbc # Session store type.

如果类路径上存在单个 Spring Session 模块,则 Spring Boot 会自动使用该存储实现。 如果有多个实现,则必须选择要用于存储会话的 StoreType,如上所示。

在后台,Spring Boot应用的配置相当于手动添加注释。 这将创建一个名为 的 Spring Bean。该 bean 实现 . 过滤器负责替换 Spring Session 支持的实现。@EnableJdbcHttpSessionspringSessionRepositoryFilterFilterHttpSession

您可以使用 进一步自定义。 以下列表显示了如何执行此操作:application.properties

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 Boot 文档的 Spring Session 部分。

配置DataSource

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

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 文档的配置 DataSource 部分。

Servlet 容器初始化

我们的 Spring Boot 配置创建了一个名为 Spring Bean 的 Spring Bean,该 Bean 实现了 . Bean 负责用 Spring Session 支持的自定义实现替换 bean。springSessionRepositoryFilterFilterspringSessionRepositoryFilterHttpSession

为了让我们发挥它的魔力,Spring 需要加载我们的类。 最后,我们需要确保我们的 Servlet 容器(即 Tomcat)对每个请求都使用我们的容器。 幸运的是,Spring Boot 为我们处理了这两个步骤。FilterConfigspringSessionRepositoryFilter

HttpSession JDBC 示例提供了如何集成 Spring Session 以及使用 Java 配置的工作示例。 您可以在接下来的几节中阅读集成的基本步骤,但我们鼓励您在与自己的应用程序集成时遵循详细的 HttpSession JDBC 指南。HttpSession
1 注释将创建名称为 的 Spring Bean。 该 bean 实现 . 过滤器负责替换 Spring Session 支持的实现。 在这种情况下,Spring Session 由关系数据库提供支持。@EnableJdbcHttpSessionspringSessionRepositoryFilterFilterHttpSession
2 我们创建一个将 Spring Session 连接到 H2 数据库的嵌入式实例。 我们将 H2 数据库配置为使用 Spring Session 中包含的 SQL 脚本创建数据库表。dataSource
3 我们创建一个来管理先前配置的事务。transactionManagerdataSource
我们类的名称(初始值设定项)无关紧要。 重要的是我们扩展.AbstractHttpSessionApplicationInitializer
1 第一步是扩展 . 这样做可以确保每个请求都向 Servlet 容器注册名为 Spring bean。AbstractHttpSessionApplicationInitializerspringSessionRepositoryFilter
2 AbstractHttpSessionApplicationInitializer还提供了一种机制来确保 Spring 加载我们的 .Config
1 此限定符声明 springSession 将使用 firstDataSource。
HttpSession JDBC XML 示例提供了如何集成 Spring Session 和使用 XML 配置的工作示例。 您可以阅读接下来几节中集成的基本步骤,但我们鼓励您在与自己的应用程序集成时遵循详细的 HttpSession JDBC XML 指南。HttpSession
1 我们使用 和 的组合,因为 Spring Session 还没有提供 XML 命名空间支持(参见 gh-104)。 这将创建一个名为 的 Spring Bean。 该 bean 实现 . 过滤器负责替换 Spring Session 支持的实现。 在这种情况下,Spring Session 由关系数据库提供支持。<context:annotation-config/>JdbcHttpSessionConfigurationspringSessionRepositoryFilterFilterHttpSession
2 我们创建一个将 Spring Session 连接到 H2 数据库的嵌入式实例。 我们将 H2 数据库配置为使用 Spring Session 中包含的 SQL 脚本创建数据库表。dataSource
3 我们创建一个来管理先前配置的事务。transactionManagerdataSource
HttpSession JDBC Spring Boot 示例提供了如何集成 Spring Session 和使用 Spring Boot 的工作示例。 您可以阅读接下来几节中的集成基本步骤,但我们建议您在与自己的应用程序集成时遵循详细的 HttpSession JDBC Spring Boot 指南。HttpSession

使用 Hazelcast 的 HttpSession

通过在使用 .HttpSessionHttpSession

本节介绍如何使用基于 Java 的配置将 Hazelcast 用于后退。HttpSession

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

Spring 配置

添加所需的依赖项后,我们可以创建 Spring 配置。 Spring 配置负责创建一个 servlet 过滤器,该过滤器将实现替换为 Spring Session 支持的实现。 为此,请添加以下 Spring 配置:HttpSession

@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 注解创建一个名为 的 Spring bean,用于实现 。 过滤器负责替换 Spring Session 支持的实现。 在这种情况下,Spring Session 由 Hazelcast 提供支持。@EnableHazelcastHttpSessionspringSessionRepositoryFilterFilterHttpSession
2 为了支持按主体名称索引检索会话,需要注册适当的会话。 Spring Session为此目的提供了条件。ValueExtractorPrincipalNameExtractor
3 为了有效地序列化对象,需要注册。如果这 未设置,Hazelcast 将使用本机 Java 序列化序列化会话。MapSessionHazelcastSessionSerializer
4 我们创建一个将 Spring Session 连接到 Hazelcast。 默认情况下,应用程序启动并连接到 Hazelcast 的嵌入式实例。 有关配置 Hazelcast 的更多信息,请参阅参考文档HazelcastInstance
如果首选,则需要在所有 Hazelcast 集群成员启动之前对其进行配置。 在 Hazelcast 群集中,所有成员都应对会话使用相同的序列化方法。此外,如果 Hazelcast 客户端/服务器拓扑 ,则成员和客户端必须使用相同的序列化方法。序列化程序可以通过相同的成员进行注册。HazelcastSessionSerializerClientConfigSerializerConfiguration

Servlet 容器初始化

我们的 Spring Configuration 创建了一个名为 的 Spring Bean,用于实现 . Bean 负责用 Spring Session 支持的自定义实现替换 bean。springSessionRepositoryFilterFilterspringSessionRepositoryFilterHttpSession

为了让我们发挥它的魔力,Spring 需要加载我们的类。 由于我们的应用程序已经在使用我们的类加载 Spring 配置,我们可以将我们的类添加到其中。 以下列表显示了如何执行此操作:FilterSessionConfigSecurityInitializerSessionConfig

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

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

}

最后,我们需要确保我们的 Servlet 容器(即 Tomcat)对每个请求都使用我们的容器。 在 Spring Security 的 . 这样做可以确保 Spring Security 使用的 Spring Session 支持。 幸运的是,Spring Session 提供了一个名为 Utility 类的实用程序类,使执行此操作变得如此简单。 以下示例演示如何执行此操作:springSessionRepositoryFilterspringSessionRepositoryFilterspringSecurityFilterChainHttpSessionAbstractHttpSessionApplicationInitializer

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

}
我们类 () 的名称无关紧要。重要的是我们扩展.InitializerAbstractHttpSessionApplicationInitializer

通过扩展,我们确保在 Spring Security 之前,为每个请求注册名为 Spring Bean 的 Spring Bean 的 servlet 容器。AbstractHttpSessionApplicationInitializerspringSessionRepositoryFilterspringSecurityFilterChain

Hazelcast Spring 示例提供了如何集成 Spring Session 和使用 Java 配置的工作示例。 您可以在接下来的几节中阅读集成的基本步骤,但我们鼓励您在与自己的应用程序集成时遵循详细的 Hazelcast Spring 指南。HttpSession
1 注解创建一个名为 的 Spring bean,用于实现 。 过滤器负责替换 Spring Session 支持的实现。 在这种情况下,Spring Session 由 Hazelcast 提供支持。@EnableHazelcastHttpSessionspringSessionRepositoryFilterFilterHttpSession
2 为了支持按主体名称索引检索会话,需要注册适当的会话。 Spring Session为此目的提供了条件。ValueExtractorPrincipalNameExtractor
3 为了有效地序列化对象,需要注册。如果这 未设置,Hazelcast 将使用本机 Java 序列化序列化会话。MapSessionHazelcastSessionSerializer
4 我们创建一个将 Spring Session 连接到 Hazelcast。 默认情况下,应用程序启动并连接到 Hazelcast 的嵌入式实例。 有关配置 Hazelcast 的更多信息,请参阅参考文档HazelcastInstance
如果首选,则需要在所有 Hazelcast 集群成员启动之前对其进行配置。 在 Hazelcast 群集中,所有成员都应对会话使用相同的序列化方法。此外,如果 Hazelcast 客户端/服务器拓扑 ,则成员和客户端必须使用相同的序列化方法。序列化程序可以通过相同的成员进行注册。HazelcastSessionSerializerClientConfigSerializerConfiguration
我们类 () 的名称无关紧要。重要的是我们扩展.InitializerAbstractHttpSessionApplicationInitializer

集成的工作原理HttpSession

幸运的是,和 (用于获取 的 API) 都是接口。 这意味着我们可以为每个 API 提供自己的实现。HttpSessionHttpServletRequestHttpSession

本节介绍 Spring Session 如何提供与 的透明集成。我们提供此内容,以便您可以了解幕后发生的事情。此功能已集成,您无需自行实现此逻辑。HttpSession

首先,我们创建一个自定义,该自定义实现返回 。 它看起来像下面这样:HttpServletRequestHttpSession

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 ...
}

任何返回 an 的方法都将被重写。 所有其他方法都由原始实现实现并委托给原始实现。HttpSessionHttpServletRequestWrapperHttpServletRequest

我们使用名为 的 servlet 替换实现。 以下伪代码显示了它的工作原理:HttpServletRequestFilterSessionRepositoryFilter

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);
	}

	// ...
}

通过将自定义实现传递到 ,我们确保在使用自定义实现之后调用的任何内容。 这凸显了为什么将Spring Session放在与 .HttpServletRequestFilterChainFilterHttpSessionSessionRepositoryFilterHttpSession

本节介绍 Spring Session 如何提供与 的透明集成。我们提供此内容,以便您可以了解幕后发生的事情。此功能已集成,您无需自行实现此逻辑。HttpSession

HttpSession和 RESTful API

Spring Session 可以通过在标头中提供会话来使用 RESTful API。

REST 示例提供了一个工作示例,说明如何在 REST 应用程序中使用 Spring Session 来支持使用标头进行身份验证。 您可以按照以下几节中描述的基本集成步骤进行操作,但我们建议您在与自己的应用程序集成时遵循详细的 REST 指南。

Spring 配置

添加所需的依赖项后,我们可以创建 Spring 配置。 Spring 配置负责创建一个 servlet 过滤器,该过滤器将实现替换为 Spring Session 支持的实现。 为此,请添加以下 Spring 配置:HttpSession

@Configuration
@EnableRedisHttpSession (1)
public class HttpSessionConfig {

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

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

}
1 注解创建一个名为 的 Spring bean,用于实现 。 过滤器负责替换 Spring Session 支持的实现。 在这种情况下,Spring Session 由 Redis 提供支持。@EnableRedisHttpSessionspringSessionRepositoryFilterFilterHttpSession
2 我们创建一个将 Spring Session 连接到 Redis 服务器。 我们将连接配置为连接到默认端口 (6379) 上的 localhost。 有关配置 Spring Data Redis 的更多信息,请参阅参考文档RedisConnectionFactory
3 我们自定义 Spring Session 的 HttpSession 集成,以使用 HTTP 标头而不是 cookie 来传达当前会话信息。

Servlet 容器初始化

我们的 Spring Configuration 创建了一个名为 的 Spring Bean,用于实现 . Bean 负责用 Spring Session 支持的自定义实现替换 bean。springSessionRepositoryFilterFilterspringSessionRepositoryFilterHttpSession

为了让我们发挥它的魔力,Spring 需要加载我们的类。 我们在 Spring 中提供了配置,如下例所示:FilterConfigMvcInitializer

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

最后,我们需要确保我们的 Servlet 容器(即 Tomcat)对每个请求都使用我们的容器。 幸运的是,Spring Session 提供了一个名为 Utility 类的实用程序类,使执行此操作变得容易。为此,请使用默认构造函数扩展类,如以下示例所示:springSessionRepositoryFilterAbstractHttpSessionApplicationInitializer

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

}
我们类 () 的名称无关紧要。重要的是我们扩展.InitializerAbstractHttpSessionApplicationInitializer
REST 示例提供了一个工作示例,说明如何在 REST 应用程序中使用 Spring Session 来支持使用标头进行身份验证。 您可以按照以下几节中描述的基本集成步骤进行操作,但我们建议您在与自己的应用程序集成时遵循详细的 REST 指南。
1 注解创建一个名为 的 Spring bean,用于实现 。 过滤器负责替换 Spring Session 支持的实现。 在这种情况下,Spring Session 由 Redis 提供支持。@EnableRedisHttpSessionspringSessionRepositoryFilterFilterHttpSession
2 我们创建一个将 Spring Session 连接到 Redis 服务器。 我们将连接配置为连接到默认端口 (6379) 上的 localhost。 有关配置 Spring Data Redis 的更多信息,请参阅参考文档RedisConnectionFactory
3 我们自定义 Spring Session 的 HttpSession 集成,以使用 HTTP 标头而不是 cookie 来传达当前会话信息。
我们类 () 的名称无关紧要。重要的是我们扩展.InitializerAbstractHttpSessionApplicationInitializer

HttpSessionListener

Spring Session 通过转换和 into 通过声明来支持 。 要使用此支持,您需要:HttpSessionListenerSessionDestroyedEventSessionCreatedEventHttpSessionEventSessionEventHttpSessionListenerAdapter

  • 确保您的实现支持并配置为触发 和 。SessionRepositorySessionDestroyedEventSessionCreatedEvent

  • 配置为 Spring Bean。SessionEventHttpSessionListenerAdapter

  • 将每个注入HttpSessionListenerSessionEventHttpSessionListenerAdapter

如果您使用 Redis 支持并设置为 ,您需要做的就是将每个都注册为 bean。 例如,假设您要支持 Spring Security 的并发控制,并且需要使用 .在这种情况下,您可以添加为 bean。 在 Java 配置中,这可能如下所示:enableIndexingAndEventstrue@EnableRedisHttpSession(enableIndexingAndEvents = true)HttpSessionListenerHttpSessionEventPublisherHttpSessionEventPublisher

@Configuration
@EnableRedisHttpSession
public class RedisHttpSessionConfig {

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

	// ...

}

在 XML 配置中,这可能如下所示:

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