Spring Session Management – Spring Session JDBC
Spring Session Module提供用于管理Web应用程序中用户会话的API和实现。
Spring会话
Spring Session由以下模块组成:
Spring Session Core:为会话管理提供API和核心支持。
Spring Session JDBC:使用关系数据库提供会话管理。
Spring Session Data Redis:为Redis数据库提供会话管理实现。
Spring Session Hazelcast:使用Hazelcast提供会话管理支持。
Spring会话的好处
Spring Session将会话管理逻辑与应用程序分离开来,从而使其更具容错能力。
Spring Session将用户会话信息保存在数据库中,因此,在具有多个服务器节点的集群环境中使用它非常有用。
我们不需要粘性会话或者会话复制逻辑。如果应用程序崩溃,则用户会话数据不会丢失。
再次启动应用程序时,它将获取所有用户会话数据。只需更改一些配置,我们就可以在会话存储软件之间进行切换,我们可以从使用Redis切换到JDBC。
Spring是一个开源项目,很容易引导。
如果您遇到任何问题,很有可能会在网上轻松找到解决方案。
Spring Session JDBC示例
让我们创建一个简单的Spring Session JDBC示例项目。
我将在应用程序中使用Spring Boot和MySQL数据库。
因此,我们需要在项目中遵循以下依赖关系。
spring-boot-starter-web:这是一个Spring MVC Web应用程序。
spring-boot-starter-jdbc:用于Spring Boot JDBC支持和自动配置。
spring-boot-starter-thymeleaf:这是为了支持Thymeleaf用于我们的视图页面。
Thymeleaf易于使用,并且与Spring框架集成良好。spring-session-core:Spring Session Core API
spring-session-jdbc:Spring Session JDBC实现
mysql-connector-java:MySQL JDBC驱动程序Jar
这是我们最终的pom.xml文件:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.theitroad.spring</groupId> <artifactId>Spring-Session-Example</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>Spring-Session-Example</name> <description>Spring Session Example</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.3.RELEASE</version> <relativePath <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>10</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-core</artifactId> </dependency> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-jdbc</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
您可以使用Spring Initializr生成基础Maven项目,然后添加所需的依赖项。
下图显示了Spring Tool Suite的最终项目结构。
让我们一一看一下每个组件。
application.properties
这是我们指定数据库配置和一些spring会话属性的地方。
spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/SpringSessionDB spring.datasource.username=theitroad spring.datasource.password=theitroad spring.session.store-type=jdbc spring.session.jdbc.initialize-schema=always spring.session.timeout.seconds=900
我将" spring.session.jdbc.initialize-schema"指定为" always",以便Spring为我们创建所需的表。
通常,在生产环境中,应用程序用户没有执行DDL语句的特权,在这种情况下,请将此属性设置为"从不",并根据JAR文件中提供的脚本手动创建数据库表。
index.html
这是我们使用Thymeleaf构建的视图页面。
<!DOCTYPE html> <html lang="en" xmlns:th="https://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Spring Session JDBC Example</title> </head> <body> <div> <form th:action="@{/saveMessage}" method="post"> <textarea name="msg" cols="40" rows="2"></textarea> <br> <input type="submit" value="Save Message" </form> </div> <div> <h2>Messages</h2> <ul th:each="m : ${messages}"> <li th:text="${m}">msg</li> </ul> </div> <div> <form th:action="@{/invalidate}" method="post"> <input type="submit" value="Destroy Session" </form> </div> </body> </html>
注意,/saveMessage
将用于向服务器发送消息。
我们将把此消息保存到用户会话属性。
当请求主页时," messages"属性将被设置为model。
因此,如果用户会话有效,则应该在主页上看到所有已保存的消息。
Spring会话使用Cookies来标识用户会话,因此,如果您点击reload,那么您还将看到所有先前保存的消息。
最后,有一个按钮可以使会话无效并销毁会话。
会话销毁后,其属性将被删除,您将看不到之前保存的邮件。
HomeController.java
这是我们的控制器类,用于处理用户请求并将消息保存到用户会话属性。
package com.theitroad.spring; import java.util.ArrayList; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; @Controller public class HomeController { @GetMapping("/") public String home(Model model, HttpSession session) { @SuppressWarnings("unchecked") List<String> msgs = (List<String>) session.getAttribute("MY_MESSAGES"); if (msgs == null) { msgs = new ArrayList<>(); } model.addAttribute("messages", msgs); return "index"; } @PostMapping("/saveMessage") public String saveMessage(@RequestParam("msg") String msg, HttpServletRequest request) { @SuppressWarnings("unchecked") List<String> msgs = (List<String>) request.getSession().getAttribute("MY_MESSAGES"); if (msgs == null) { msgs = new ArrayList<>(); request.getSession().setAttribute("MY_MESSAGES", msgs); } msgs.add(msg); request.getSession().setAttribute("MY_MESSAGES", msgs); return "redirect:/"; } @PostMapping("/invalidate") public String destroySession(HttpServletRequest request) { request.getSession().invalidate(); return "redirect:/"; } }
大多数逻辑很简单,请注意我们没有使用Spring Session模块中的任何东西。
这是spring框架的优点,它将自动配置我们的应用程序以使用数据库进行会话管理。
SpringSessionExampleApplication.java
只是一个Spring Boot应用程序来运行我们的应用程序。
package com.theitroad.spring; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SpringSessionExampleApplication { public static void main(String[] args) { SpringApplication.run(SpringSessionExampleApplication.class, args); } }
Spring Session JDBC测试
我们的应用程序已经准备就绪,只需将SpringSessionExampleApplication类作为Java应用程序运行即可。
您会在控制台日志中注意到以下映射。
Mapped "{[/saveMessage],methods=[POST]}" onto public java.lang.String com.theitroad.spring.HomeController.saveMessage(java.lang.String,javax.servlet.http.HttpServletRequest) Mapped "{[/invalidate],methods=[POST]}" onto public java.lang.String com.theitroad.spring.HomeController.destroySession(javax.servlet.http.HttpServletRequest) Mapped "{[/],methods=[GET]}" onto public java.lang.String com.theitroad.spring.HomeController.home(org.springframework.ui.Model,javax.servlet.http.HttpSession)
您还将注意到记录器执行SQL脚本以创建数据库表。
Executing SQL script from class path resource [org/springframework/session/jdbc/schema-mysql.sql]
您也可以在数据库中检查这些表。
如日志所示,我们的index.html页面将被自动配置为欢迎页面。
2016-06-27 12:50:09.761 INFO 1666 --- [main] o.s.b.a.w.s.WelcomePageHandlerMapping: Adding welcome page template: index