Spring Session
Spring Session 提供了一个管理用户session信息的接口和实现
1.介绍
Spring Session 提供了一个管理用户session信息的接口和实现,同时也使得支持集群会话变得微不足道,而不依赖于特定于应用程序容器的解决方案。 它还提供透明集成:
HttpSession - 允许以应用程序容器(即Tomcat)中立的方式替换HttpSession,支持在头文件中提供会话ID以使用RESTful API。
WebSocket - 提供在接收WebSocket消息时保持HttpSession存活的能力
WebSession - 允许以应用程序容器中立方式替换Spring WebFlux的WebSession。
2.新特性
以下是Spring Session 2.0新增内容的重点。 您可以通过参考2.0.0.M1,2.0.0.M2,2.0.0.M3,2.0.0.M4,2.0.0.M5,2.0.0.RC1的更改日志找到新的完整列表。 ,2.0.0.RC2和2.0.0.RELEASE。
升级到Java 8和Spring Framework 5作为基线
添加了使用Redis ReactiveSessionRepository管理Spring WebFlux的WebSession的支持
提取SessionRepository实现以分离模块
改进了Session和SessionRepository API
为所有支持的会话存储提供改进和协调的配置支持
添加了使用SessionCookieConfig配置默认CookieSerializer的支持
大量的性能改进和错误修复
3.样例和指南
如果您希望开始使用Spring Session,最好的起点是我们的示例应用程序。
表1.使用Spring Boot的示例应用程序
代码 | 描述 | 手册
---------|--------|-------
[HttpSession 使用 Redis](https://github.com/spring-projects/spring-session/tree/2.1.0.RELEASE/samples/boot/redis) | 演示如何将HttpSession替换为Spring Session使用Redis 。 | [HttpSession 使用 Redis 手册](https://docs.spring.io/spring-session/docs/2.1.0.RELEASE/reference/html5/guides/boot-redis.html)
[HttpSession with JDBC](https://github.com/spring-projects/spring-session/tree/2.1.0.RELEASE/samples/boot/jdbc) | 演示如何使用关系数据库存储session替代httpsession. | [HttpSession with JDBC Guide](https://docs.spring.io/spring-session/docs/2.1.0.RELEASE/reference/html5/guides/boot-jdbc.html)
[Find by Username](https://github.com/spring-projects/spring-session/tree/2.1.0.RELEASE/samples/boot/findbyusername) | 演示如何使用spring session 根据用户名查找session. | [Find by Username Guide](https://docs.spring.io/spring-session/docs/2.1.0.RELEASE/reference/html5/guides/boot-findbyusername.html)
[WebSockets](https://github.com/spring-projects/spring-session/tree/2.1.0.RELEASE/samples/boot/websocket) | 演示如何与Websockets一起使用Spring Session. | [WebSockets Guide](https://docs.spring.io/spring-session/docs/2.1.0.RELEASE/reference/html5/guides/boot-websocket.html)
[WebFlux](https://github.com/spring-projects/spring-session/tree/2.1.0.RELEASE/samples/boot/webflux) | 演示如何使用redis 让Spring Session替换 Spring WebFlux’s `WebSession`. | TBD
[HttpSession with Redis JSON serialization](https://github.com/spring-projects/spring-session/tree/2.1.0.RELEASE/samples/boot/redis-json) | 演示如何使用Spring Session替换 HttpSession 使用redis 的JSON序列化. | TBD
表 2. 基于java配置的样例程序
| 代码 | 描述 | 手册 |
| --- | --- | --- |
| [HttpSession with Redis](https://github.com/spring-projects/spring-session/tree/2.1.0.RELEASE/samples/javaconfig/redis) | 演示如何将HttpSession替换为Spring Session使用Redis 。 | [HttpSession with Redis Guide](https://docs.spring.io/spring-session/docs/2.1.0.RELEASE/reference/html5/guides/java-redis.html) |
| [HttpSession with JDBC](https://github.com/spring-projects/spring-session/tree/2.1.0.RELEASE/samples/javaconfig/jdbc) | 演示如何使用关系数据库存储session替代httpsession. | [HttpSession with JDBC Guide](https://docs.spring.io/spring-session/docs/2.1.0.RELEASE/reference/html5/guides/java-jdbc.html) |
| [HttpSession with Hazelcast](https://github.com/spring-projects/spring-session/tree/2.1.0.RELEASE/samples/javaconfig/hazelcast) | 演示使用Spring Session和Hazelcast 替换 HttpSession . | [HttpSession with Hazelcast Guide](https://docs.spring.io/spring-session/docs/2.1.0.RELEASE/reference/html5/guides/java-hazelcast.html) |
| [Custom Cookie](https://github.com/spring-projects/spring-session/tree/2.1.0.RELEASE/samples/javaconfig/custom-cookie) | 演示如何使用Spring Session自定义cookie. | [Custom Cookie Guide](https://docs.spring.io/spring-session/docs/2.1.0.RELEASE/reference/html5/guides/java-custom-cookie.html) |
| [Spring Security](https://github.com/spring-projects/spring-session/tree/2.1.0.RELEASE/samples/javaconfig/security) | 演示如何在一个已经存在的spring security应用中使用Spring Session. | [Spring Security Guide](https://docs.spring.io/spring-session/docs/2.1.0.RELEASE/reference/html5/guides/java-security.html) |
| [REST](https://github.com/spring-projects/spring-session/tree/2.1.0.RELEASE/samples/javaconfig/rest) | 演示如何使用Spring Session 在一个REST应用中支持头信息认证. | [REST Guide](https://docs.spring.io/spring-session/docs/2.1.0.RELEASE/reference/html5/guides/java-rest.html) |
表 3.使用基于Spring XML配置的样例程序
| 代码 | 描述 | 手册 |
| --- | --- | --- |
| [HttpSession with Redis](https://github.com/spring-projects/spring-session/tree/2.1.0.RELEASE/samples/xml/redis) | 演示如何将HttpSession替换为Spring Session使用Redis存储. | [HttpSession with Redis Guide](https://docs.spring.io/spring-session/docs/2.1.0.RELEASE/reference/html5/guides/xml-redis.html) |
| [HttpSession with JDBC](https://github.com/spring-projects/spring-session/tree/2.1.0.RELEASE/samples/xml/jdbc) | 演示如何使用Spring Session和关系数据库存储替代httpsession. . | [HttpSession 和 JDBC 手册](https://docs.spring.io/spring-session/docs/2.1.0.RELEASE/reference/html5/guides/xml-jdbc.html) |
表 4. 小例子
| Source | Description | Guide |
| --- | --- | --- |
| [Grails 3](https://github.com/spring-projects/spring-session/tree/2.1.0.RELEASE/samples/misc/grails3)| 演示 Spring Session 和 Grails 3一起使用.| [Grails 3 手册](https://docs.spring.io/spring-session/docs/2.1.0.RELEASE/reference/html5/guides/grails3.html) |
| [Hazelcast](https://github.com/spring-projects/spring-session/tree/2.1.0.RELEASE/samples/misc/hazelcast) |演示在javaEE应用中使用Spring Session和Hazelcast.| TBD |
4.Spring Session模块
在Spring Session 1.x中,所有Spring Session的SessionRepository实现都在spring-session组件中可用。 虽然方便,但随着更多功能和SessionRepository实现添加到项目中,这种方法不可能长期持续。
从Spring Session 2.0开始,该项目已经拆分为Spring Session Core模块,以及其他几个带有SessionRepository实现和与特定数据存储相关的功能的模块。Spring Data的用户会发现这种安排很熟悉,Spring Session Core模块扮演的角色相当于Spring Data Commons,并提供核心功能和API以及其他包含数据存储特定实现的模块。作为此拆分的一部分,Spring Session Data MongoDB和Spring Session Data GemFire模块被移动到单独的存储库,因此项目的存储库/模块的情况如下:
[`spring-session` repository](https://github.com/spring-projects/spring-session)
Spring Session Core,Spring Session Data Redis,Spring Session JDBC和Spring Session Hazelcast模块
[`spring-session-data-mongodb` repository](https://github.com/spring-projects/spring-session-data-mongodb)
Spring会话数据MongoDB模块
[`spring-session-data-geode` repository](https://github.com/spring-projects/spring-session-data-geode)
Spring Session Data Geode和Spring Session Data Geode模块
最后,Spring Session现在还提供了Maven BOM(如“物料清单”)模块,以帮助用户解决版本管理问题:
[`spring-session-bom` repository](https://github.com/spring-projects/spring-session-bom)
Spring Session BOM 模块
5.HttpSession整合
Spring Session提供与HttpSession的透明集成。 这意味着开发人员可以使用Spring Session支持的实现来切换HttpSession实现。
5.1. 为什么需要 Spring Session 整合 HttpSession?
我们已经提到Spring Session提供了与HttpSession的透明集成,但是我们从中获得了什么好处呢?
集群会话 - Spring会话使得支持集群会话变得微不足道,而不依赖于特定于应用程序容器的解决方案。
RESTful API - Spring Session允许在标头中提供会话ID以使用RESTful API
5.2. HttpSession 和 Redis
通过在使用HttpSession的任何东西之前添加Servlet过滤器来启用使用Spring Session和HttpSession。 您可以选择启用此功能:
* [基于java config](https://docs.spring.io/spring-session/docs/2.1.0.RELEASE/reference/html5/#httpsession-redis-jc)
* [基于XML配置](https://docs.spring.io/spring-session/docs/2.1.0.RELEASE/reference/html5/#httpsession-redis-xml)
5.2.1. 基于Java的redis配置
本节介绍如何基于Java的配置使用Redis来支持HttpSession。
[HttpSession示例](https://docs.spring.io/spring-session/docs/2.1.0.RELEASE/reference/html5/#samples)提供了有关如何使用Java配置集成Spring Session和HttpSession的工作示例。 您可以在下面阅读集成的基本步骤,但建议您在与自己的应用程序集成时遵循详细的HttpSession指南。
Spring Java 配置
添加所需的依赖项后,我们可以创建Spring配置。 Spring配置负责创建一个Servlet过滤器,该过滤器用Spring Session支持的实现替换HttpSession实现。 添加以下Spring配置:
@EnableRedisHttpSession
public class Config {
@Bean
public LettuceConnectionFactory connectionFactory() {
return new LettuceConnectionFactory();
}
}
@EnableRedisHttpSession注释创建一个名为springSessionRepositoryFilter的Spring Bean,它实现了Filter。 过滤器负责替换由Spring Session支持的HttpSession实现。 在这种情况下,Spring Session由Redis提供支持。
我们创建了一个RedseConnectionFactory,它将Spring Session连接到Redis Server。 我们将连接配置为在默认端口上连接到localhost(6379)有关配置Spring Data Redis的更多信息,请参阅参考文档。
Java Servlet 容器初始化
我们的Spring配置创建了一个名为springSessionRepositoryFilter的Spring Bean,它实现了Filter。 springSessionRepositoryFilter bean负责将HttpSession替换为Spring Session支持的自定义实现。
为了使我们的Filter能够发挥其魔力,Spring需要加载我们的Config类。 最后,我们需要确保我们的Servlet容器(即Tomcat)对每个请求都使用springSessionRepositoryFilter。 幸运的是,Spring Session提供了一个名为AbstractHttpSessionApplicationInitializer的实用程序类,这两个步骤都非常简单。 你可以在下面找到一个例子:
src/main/java/sample/Initializer.java
public class Initializer extends AbstractHttpSessionApplicationInitializer {
public Initializer() {
super(Config.class);
}
}
我们类的名字(初始化程序)并不重要。 重要的是我们扩展了AbstractHttpSessionApplicationInitializer。
第一步是扩展AbstractHttpSessionApplicationInitializer。 这确保了名为springSessionRepositoryFilter的Spring Bean为每个请求注册了我们的Servlet容器。
AbstractHttpSessionApplicationInitializer还提供了一种机制,可以轻松确保Spring加载我们的Config。
5.2.2. Redis 基于XML 配置
本节介绍如何使用Redis使用基于XML的配置来支持HttpSession。
[HttpSession XML示例](https://docs.spring.io/spring-session/docs/2.1.0.RELEASE/reference/html5/#samples)提供了有关如何使用XML配置集成Spring Session和HttpSession的工作示例。 您可以在下面阅读集成的基本步骤,但建议您在与自己的应用程序集成时遵循详细的HttpSession XML指南。
Spring XML 配置
添加所需的依赖项后,我们可以创建Spring配置。 Spring配置负责创建一个Servlet过滤器,该过滤器用Spring Session支持的实现替换HttpSession实现。 添加以下Spring配置:
src/main/webapp/WEB-INF/spring/session.xml
<context:annotation-config/>
<bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"/>
<bean class="org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory"/>
我们使用<context:annotation-config />和RedisHttpSessionConfiguration的组合,因为Spring Session尚未提供XML Namespace支持(请参阅gh-104)。 这将创建一个名为springSessionRepositoryFilter的Spring Bean,它实现了Filter。 过滤器负责替换由Spring Session支持的HttpSession实现。 在这种情况下,Spring Session由Redis提供支持。
我们创建了一个RedseConnectionFactory,它将Spring Session连接到Redis Server。 我们将连接配置为在默认端口上连接到localhost(6379)有关配置Spring Data Redis的更多信息,请参阅参考文档。
XML Servlet 容器初始化
我们的Spring配置创建了一个名为springSessionRepositoryFilter的Spring Bean,它实现了Filter。 springSessionRepositoryFilter bean负责将HttpSession替换为Spring Session支持的自定义实现。
为了让我们的Filter发挥其魔力,我们需要指示Spring加载我们的session.xml配置。 我们使用以下配置执行此操作:
src/main/webapp/WEB-INF/web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/*.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将以springSessionRepositoryFilter的名称查找Bean并将其强制转换为Filter。 对于调用DelegatingFilterProxy的每个请求,将调用springSessionRepositoryFilter。
5.3. HttpSession 和 JDBC
通过在使用HttpSession的任何东西之前添加Servlet过滤器来启用使用Spring Session和HttpSession。 您可以选择启用此功能:
* [Java 配置](https://docs.spring.io/spring-session/docs/2.1.0.RELEASE/reference/html5/#httpsession-jdbc-jc)
* [XML 配置](https://docs.spring.io/spring-session/docs/2.1.0.RELEASE/reference/html5/#httpsession-jdbc-xml)
* [基于Spring Boot配置](https://docs.spring.io/spring-session/docs/2.1.0.RELEASE/reference/html5/#httpsession-jdbc-boot)
#### [](https://docs.spring.io/spring-session/docs/2.1.0.RELEASE/reference/html5/#httpsession-jdbc-jc)
5.3.1. 基于java的JDBC配置
本节介绍如何使用关系数据库来使用基于Java的配置来支持HttpSession。
[HttpSession JDBC示例](https://docs.spring.io/spring-session/docs/2.1.0.RELEASE/reference/html5/#samples)提供了有关如何使用Java配置集成Spring Session和HttpSession的工作示例。 您可以在下面阅读集成的基本步骤,但是在与您自己的应用程序集成时,建议您遵循详细的HttpSession JDBC指南。
Spring Java 配置
添加所需的依赖项后,我们可以创建Spring配置。 Spring配置负责创建一个Servlet过滤器,该过滤器用Spring Session支持的实现替换HttpSession实现。 添加以下Spring配置:
@EnableJdbcHttpSession
public class Config {
@Bean
public EmbeddedDatabase dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.addScript("org/springframework/session/jdbc/schema-h2.sql").build();
}
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
@EnableJdbcHttpSession注释创建一个名为springSessionRepositoryFilter的Spring Bean,它实现了Filter。 过滤器负责替换由Spring Session支持的HttpSession实现。 在这种情况下,Spring Session由关系数据库支持。
我们创建了一个dataSource,它将Spring Session连接到H2数据库的嵌入式实例。 我们将H2数据库配置为使用Spring Session中包含的SQL脚本创建数据库表。
我们创建一个transactionManager来管理先前配置的dataSource的事务。
有关如何配置与数据访问相关的问题的其他信息,请参阅[Spring 框架参考手册](https://docs.spring.io/spring/docs/5.1.1.RELEASE/spring-framework-reference/data-access.html)。
Java Servlet 容器初始化
我们的[Spring配置](https://docs.spring.io/spring-session/docs/2.1.0.RELEASE/reference/html5/#httpsession-spring-configuration)创建了一个名为springSessionRepositoryFilter的Spring Bean,它实现了Filter。 springSessionRepositoryFilter bean负责将HttpSession替换为Spring Session支持的自定义实现。
为了使我们的Filter能够发挥其魔力,Spring需要加载我们的Config类。 最后,我们需要确保我们的Servlet容器(即Tomcat)对每个请求都使用springSessionRepositoryFilter。 幸运的是,Spring Session提供了一个名为AbstractHttpSessionApplicationInitializer的实用程序类,这两个步骤都非常简单。 你可以在下面找到一个例子:
src/main/java/sample/Initializer.java
public class Initializer extends AbstractHttpSessionApplicationInitializer {
public Initializer() {
super(Config.class);
}
}
我们类的名字(Initializer)并不重要。 重要的是我们扩展了AbstractHttpSessionApplicationInitializer。
第一步是扩展AbstractHttpSessionApplicationInitializer。 这确保了名为springSessionRepositoryFilter的Spring Bean为每个我们的Servlet容器请求注册。
AbstractHttpSessionApplicationInitializer还提供了一种机制,可以轻松确保Spring加载我们的Config。
5.3.2. JDBC 基于 XML 配置
本节介绍如何使用关系数据库使用基于XML的配置来支持HttpSession。
[HttpSession JDBC XML示例](https://docs.spring.io/spring-session/docs/2.1.0.RELEASE/reference/html5/#samples)提供了有关如何使用XML配置集成Spring Session和HttpSession的工作示例。 您可以在下面阅读集成的基本步骤,但是在与您自己的应用程序集成时,建议您遵循详细的HttpSession JDBC XML指南。
Spring XML 配置
添加所需的依赖项后,我们可以创建Spring配置。 Spring配置负责创建一个Servlet过滤器,该过滤器用Spring Session支持的实现替换HttpSession实现。 添加以下Spring配置:
src/main/webapp/WEB-INF/spring/session.xml
<context:annotation-config/>
<bean class="org.springframework.session.jdbc.config.annotation.web.http.JdbcHttpSessionConfiguration"/>
<jdbc:embedded-database id="dataSource" database-name="testdb" type="H2">
<jdbc:script location="classpath:org/springframework/session/jdbc/schema-h2.sql"/>
</jdbc:embedded-database>
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg ref="dataSource"/>
</bean>
我们使用<context:annotation-config />和JdbcHttpSessionConfiguration的组合,因为Spring Session尚未提供XML Namespace支持(请参阅gh-104)。 这将创建一个名为springSessionRepositoryFilter的Spring Bean,它实现了Filter。 过滤器负责替换由Spring Session支持的HttpSession实现。 在这种情况下,Spring Session由关系数据库支持。
我们创建了一个dataSource,它将Spring Session连接到H2数据库的嵌入式实例。 我们将H2数据库配置为使用Spring Session中包含的SQL脚本创建数据库表。
我们创建一个transactionManager来管理先前配置的dataSource的事务。
有关如何配置与数据访问相关的问题的其他信息,请参阅[Spring 框架参考手册](https://docs.spring.io/spring/docs/5.1.1.RELEASE/spring-framework-reference/data-access.html)。
XML Servlet容器初始化
我们的Spring配置创建了一个名为springSessionRepositoryFilter的Spring Bean,它实现了Filter。 springSessionRepositoryFilter bean负责将HttpSession替换为Spring Session支持的自定义实现。
为了让我们的Filter发挥其魔力,我们需要指示Spring加载我们的session.xml配置。 我们使用以下配置执行此操作:
src/main/webapp/WEB-INF/web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/*.xml
</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
[ContextLoaderListener](https://docs.spring.io/spring/docs/5.1.1.RELEASE/spring-framework-reference/core.html#context-create)读取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将以springSessionRepositoryFilter的名称查找Bean并将其强制转换为Filter。 对于调用DelegatingFilterProxy的每个请求,将调用springSessionRepositoryFilter。
5.3.3. JDBC 基于Spring Boot配置
本节介绍在使用Spring Boot时如何使用关系数据库来支持HttpSession。
[HttpSession JDBC Spring Boot 示例](https://docs.spring.io/spring-session/docs/2.1.0.RELEASE/reference/html5/#samples)提供了一个关于如何使用Spring Boot集成Spring Session和HttpSession的工作示例。 您可以在下面阅读集成的基本步骤,但是在与您自己的应用程序集成时,建议您遵循详细的HttpSession JDBC Spring Boot 手册。
Spring Boot 配置
添加所需的依赖项后,我们可以创建Spring Boot配置。 由于支持一流的自动配置,设置由关系数据库支持的Spring Session就像向application.properties添加单个配置属性一样简单:
src/main/resources/application.properties
spring.session.store-type=jdbc # Session store type.
在引擎盖下,Spring Boot将应用相当于手动添加@EnableJdbcHttpSession注释的配置。 这将创建一个名为springSessionRepositoryFilter的Spring Bean,它实现了Filter。 过滤器负责替换由Spring Session支持的HttpSession实现。
使用application.properties可以进一步自定义:
src/main/resources/application.properties
server.servlet.session.timeout= # Session timeout. If a duration suffix is not specified, seconds will be 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](https://docs.spring.io/spring-boot/docs/2.1.0.M3/reference/htmlsingle/#boot-features-session)部分。
配置数据库
Spring Boot自动创建一个DataSource,将Spring Session连接到H2数据库的嵌入式实例。 在生产环境中,您需要确保更新配置以指向关系数据库。 例如,您可以在application.properties中包含以下内容
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文档的[配置数据源](https://docs.spring.io/spring-boot/docs/2.1.0.M3/reference/htmlsingle/#boot-features-configure-datasource)部分。
Servlet 容器初始化
我们的[Spring Boot配置](https://docs.spring.io/spring-session/docs/2.1.0.RELEASE/reference/html5/#httpsession-jdbc-boot-spring-configuration)创建了一个名为springSessionRepositoryFilter的Spring Bean,它实现了Filter。 springSessionRepositoryFilter bean负责将HttpSession替换为Spring Session支持的自定义实现。
为了使我们的Filter能够发挥其魔力,Spring需要加载我们的Config类。 最后,我们需要确保我们的Servlet容器(即Tomcat)对每个请求都使用springSessionRepositoryFilter。 幸运的是,Spring Boot为我们处理了这两个步骤。
5.4. HttpSession 的 Hazelcast
通过在使用HttpSession的任何东西之前添加Servlet过滤器来启用使用Spring Session和HttpSession。
本节介绍如何使用Hazelcast使用基于Java的配置来支持HttpSession。
[Hazelcast Spring示例](https://docs.spring.io/spring-session/docs/2.1.0.RELEASE/reference/html5/#samples)提供了有关如何使用Java配置集成Spring Session和HttpSession的工作示例。 您可以在下面阅读集成的基本步骤,但我们鼓励您在与自己的应用程序集成时遵循详细的Hazelcast Spring Guide。
5.4.1. Spring 配置
添加所需的依赖项后,我们可以创建Spring配置。 Spring配置负责创建一个Servlet过滤器,该过滤器用Spring Session支持的实现替换HttpSession实现。 添加以下Spring配置:
@EnableHazelcastHttpSession
@Configuration
public class HazelcastHttpSessionConfig {
@Bean
public HazelcastInstance hazelcastInstance() {
MapAttributeConfig attributeConfig = new MapAttributeConfig()
.setName(HazelcastSessionRepository.PRINCIPAL_NAME_ATTRIBUTE)
.setExtractor(PrincipalNameExtractor.class.getName());
Config config = new Config();
config.getMapConfig(HazelcastSessionRepository.DEFAULT_SESSION_MAP_NAME)
.addMapAttributeConfig(attributeConfig)
.addMapIndexConfig(new MapIndexConfig(
HazelcastSessionRepository.PRINCIPAL_NAME_ATTRIBUTE, false));
return Hazelcast.newHazelcastInstance(config);
}
}
@EnableHazelcastHttpSession注释创建一个名为springSessionRepositoryFilter的Spring Bean,它实现了Filter。 过滤器负责替换由Spring Session支持的HttpSession实现。 在这种情况下,Spring Session由Hazelcast支持。
为了支持按主体名称索引检索会话,需要注册适当的ValueExtractor。 Spring Session为此提供了PrincipalNameExtractor。
我们创建了一个将Spring Session连接到Hazelcast的HazelcastInstance。 默认情况下,Hazelcast的嵌入式实例已启动并由应用程序连接。 有关配置Hazelcast的更多信息,请参阅[参考文档](http://docs.hazelcast.org/docs/3.10.6/manual/html-single/index.html#hazelcast-configuration)。
5.4.2. Servlet 容器初始化
我们的[Spring配置](https://docs.spring.io/spring-session/docs/2.1.0.RELEASE/reference/html5/#security-spring-configuration)创建了一个名为springSessionRepositoryFilter的Spring Bean,它实现了Filter。 springSessionRepositoryFilter bean负责将HttpSession替换为Spring Session支持的自定义实现。
为了让我们的Filter能够发挥其魔力,Spring需要加载我们的SessionConfig类。 由于我们的应用程序已经使用我们的SecurityInitializer类加载Spring配置,我们可以简单地将SessionConfig类添加到它。
src/main/java/sample/SecurityInitializer.java
public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer {
public SecurityInitializer() {
super(SecurityConfig.class, SessionConfig.class);
}
}
最后,我们需要确保我们的Servlet容器(即Tomcat)对每个请求都使用springSessionRepositoryFilter。 在Spring Security的springSecurityFilterChain之前调用Spring Session的springSessionRepositoryFilter是非常重要的。 这可确保Spring Security使用的HttpSession由Spring Session支持。 幸运的是,Spring Session提供了一个名为AbstractHttpSessionApplicationInitializer的实用程序类,这使得这非常简单。 你可以在下面找到一个例子:
src/main/java/sample/Initializer.java
public class Initializer extends AbstractHttpSessionApplicationInitializer {
}
我们类的名字(Initializer)并不重要。 重要的是我们扩展了AbstractHttpSessionApplicationInitializer。
通过扩展AbstractHttpSessionApplicationInitializer,我们确保名为springSessionRepositoryFilter的Spring Bean在Spring Security的springSecurityFilterChain之前为每个请求注册了我们的Servlet容器。
5.5。 HttpSession集成如何工作
幸运的是,HttpSession和HttpServletRequest(用于获取HttpSession的API)都是接口。 这意味着我们可以为每个API提供我们自己的实现。
本节描述Spring Session如何提供与HttpSession的透明集成。 目的是让用户能够理解幕后发生的事情。 此功能已集成,您无需自己实现此逻辑。
首先,我们创建一个自定义的HttpServletRequest,它返回HttpSession的自定义实现。 它看起来像下面这样:
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实现。
我们使用名为SessionRepositoryFilter的servlet Filter替换HttpServletRequest实现。 伪代码可以在下面找到:
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);
}
// ...
}
通过将自定义HttpServletRequest实现传递到FilterChain,我们确保在Filter使用自定义HttpSession实现之后调用的任何内容。 这突出了为什么必须将Spring Session的SessionRepositoryFilter放在与HttpSession交互的任何内容之前。
5.6。 HttpSession和RESTful API
Spring Session可以通过允许在标头中提供会话来使用RESTful API。
[REST示例](https://docs.spring.io/spring-session/docs/2.1.0.RELEASE/reference/html5/#samples)提供了有关如何在REST应用程序中使用Spring Session以支持使用标头进行身份验证的工作示例。 您可以按照以下集成的基本步骤进行操作,但建议您在与自己的应用程序集成时遵循详细的REST指南。
5.6.1. Spring 配置
添加所需的依赖项后,我们可以创建Spring配置。 Spring配置负责创建一个Servlet过滤器,该过滤器用Spring Session支持的实现替换HttpSession实现。 添加以下Spring配置:
@Configuration
@EnableRedisHttpSession
public class HttpSessionConfig {
@Bean
public LettuceConnectionFactory connectionFactory() {
return new LettuceConnectionFactory();
}
@Bean
public HttpSessionIdResolver httpSessionIdResolver() {
return HeaderHttpSessionIdResolver.xAuthToken();
}
}
@EnableRedisHttpSession注释创建一个名为springSessionRepositoryFilter的Spring Bean,它实现了Filter。 过滤器负责替换由Spring Session支持的HttpSession实现。 在这种情况下,Spring Session由Redis提供支持。
我们创建了一个RedseConnectionFactory,它将Spring Session连接到Redis Server。 我们将连接配置为在默认端口上连接到localhost(6379)有关配置Spring Data Redis的更多信息,请参阅参考文档。
我们定制Spring Session的HttpSession集成以使用HTTP头来传达当前会话信息而不是cookie。
5.6.2. Servlet 容器初始化
我们的Spring配置创建了一个名为springSessionRepositoryFilter的Spring Bean,它实现了Filter。 springSessionRepositoryFilter bean负责将HttpSession替换为Spring Session支持的自定义实现。
为了使我们的Filter能够发挥其魔力,Spring需要加载我们的Config类。 我们在Spring Mvc Initializer中提供配置,如下所示:
src/main/java/sample/mvc/MvcInitializer.java
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { SecurityConfig.class, HttpSessionConfig.class };
}
最后,我们需要确保我们的Servlet容器(即Tomcat)对每个请求都使用springSessionRepositoryFilter。 幸运的是,Spring Session提供了一个名为AbstractHttpSessionApplicationInitializer的实用程序类,这使得这非常简单。 只需使用默认构造函数扩展类,如下所示:
src/main/java/sample/Initializer.java
public class Initializer extends AbstractHttpSessionApplicationInitializer {
}
我们类的名字(Initializer)并不重要。 重要的是我们扩展了AbstractHttpSessionApplicationInitializer。
5.7. HttpSessionListener
Spring Session通过声明SessionEventHttpSessionListenerAdapter将SessionDestroyedEvent和SessionCreatedEvent转换为HttpSessionEvent来支持HttpSessionListener。 要使用此支持,您需要:
确保您的SessionRepository实现支持并配置为触发SessionDestroyedEvent和SessionCreatedEvent。
将SessionEventHttpSessionListenerAdapter配置为Spring bean。
将每个HttpSessionListener注入SessionEventHttpSessionListenerAdapter
如果您正在使用HttpSession中使用Redis记录的配置支持,那么您需要做的就是将每个HttpSessionListener注册为bean。 例如,假设您要支持Spring Security的并发控制,并且需要使用HttpSessionEventPublisher,您只需将HttpSessionEventPublisher作为bean添加即可。 在Java配置中,这可能如下所示:
@Configuration
@EnableRedisHttpSession
public class RedisHttpSessionConfig {
@Bean
public HttpSessionEventPublisher httpSessionEventPublisher() {
return new HttpSessionEventPublisher();
}
// ...
}
在XML配置中,这可能如下所示:
<bean class="org.springframework.security.web.session.HttpSessionEventPublisher"/>