Spring Session - HttpSession(快速入门)
本指南描述如何在 Java 配置中使用 Spring Session 透明地利用关系型数据库来支撑 Web 应用程序的 HttpSession。
你可以在 httpsession-jdbc 示例应用程序 中找到完整的指南。
更新依赖
在使用 Spring Session 之前,你必须更新依赖。如果你使用 Maven,你必须添加以下依赖:
<dependencies>
<!-- ... -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-jdbc</artifactId>
<version>4.1.1</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>7.0.9</version>
</dependency>
</dependencies>
Spring Java 配置
添加所需依赖后,我们可以创建 Spring 配置。Spring 配置负责创建一个 Servlet 过滤器,用由 Spring Session 支撑的实现替换 HttpSession 实现。为此,添加以下 Spring 配置:
@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
}
}
@EnableJdbcHttpSession注解创建一个名为springSessionRepositoryFilter的 Spring Bean。该 bean 实现Filter。该过滤器负责将HttpSession实现替换为由 Spring Session 支撑。在本例中,Spring Session 由关系型数据库支撑。我们创建一个
dataSource,将 Spring Session 连接到嵌入式 H2 数据库实例。我们配置 H2 数据库使用 Spring Session 中包含的 SQL 脚本来创建数据库表。我们创建一个
transactionManager,为先前配置的dataSource管理事务。
有关如何配置数据访问相关事项的更多信息,请参阅 Spring Framework 参考文档。
Java Servlet 容器初始化
我们的 Spring 配置 创建了一个名为 springSessionRepositoryFilter、实现 Filter 的 Spring bean。springSessionRepositoryFilter bean 负责将 HttpSession 替换为由 Spring Session 支撑的自定义实现。
为了让我们的 Filter 发挥作用,Spring 需要加载我们的 Config 类。最后,我们需要确保 Servlet 容器(即 Tomcat)对每个请求都使用我们的 springSessionRepositoryFilter。幸运的是,Spring Session 提供了一个名为 AbstractHttpSessionApplicationInitializer 的实用类,使这两个步骤都变得容易。以下示例展示了如何这样做:
public class Initializer extends AbstractHttpSessionApplicationInitializer { 1
public Initializer() {
super(Config.class); 2
}
}
我们类的名称(Initializer)并不重要。重要的是我们扩展了 AbstractHttpSessionApplicationInitializer。
第一步是扩展
AbstractHttpSessionApplicationInitializer。这样做确保名为springSessionRepositoryFilter的 Spring bean 被注册到我们的 Servlet 容器中,对每个请求都生效。AbstractHttpSessionApplicationInitializer还提供了一种机制,确保 Spring 加载我们的Config。
多个 DataSource
Spring Session 提供 @SpringSessionDataSource 限定符,允许你显式声明应将哪个 DataSource bean 注入到 JdbcIndexedSessionRepository 中。当应用程序上下文中存在多个 DataSource bean 时,这特别有用。
以下示例展示了如何这样做:
@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() {
// ...
}
}
此限定符声明 Spring Session 应使用 firstDataSource。
httpsession-jdbc 示例应用程序
本节描述如何使用 httpsession-jdbc 示例应用程序。
运行 httpsession-jdbc 示例应用程序
你可以通过获取源代码并运行以下命令来启动示例:
$ ./gradlew :spring-session-sample-javaconfig-jdbc:tomcatRun
现在你应该可以通过 localhost:8080/ 访问该应用程序了。
探索 httpsession-jdbc 示例应用程序
现在你可以尝试使用该应用程序。为此,在表单中填写以下信息:
- 属性名称: username
- 属性值: rob
现在点击 Set Attribute 按钮。你现在应该能在表格中看到显示的值。
它是如何工作的?
我们在以下清单所示的 SessionServlet 中与标准 HttpSession 交互:
@WebServlet("/session")
public class SessionServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String attributeName = req.getParameter("attributeName");
String attributeValue = req.getParameter("attributeValue");
req.getSession().setAttribute(attributeName, attributeValue);
resp.sendRedirect(req.getContextPath() + "/");
}
private static final long serialVersionUID = 2878267318695777395L;
}
如果你愿意,可以通过以下地址提供的 H2 Web 控制台移除会话:localhost:8080/h2-console/(JDBC URL 使用 jdbc:h2:mem:testdb)。
现在你可以访问 localhost:8080/ 上的应用程序,并看到我们添加的属性不再显示。