在SpringBoot2+SpringSession中使用数据库
实际上由于信息混乱,导致需要额外的时间来使其正常运作(´・ω・)
目标
使用SpringBoot2和SpringSession来将会话信息存储在数据库中进行管理。
运行环境和版本信息
我正在以下进行操作验证。
-
- SpringBoot 2.0.5.RELEASE。
-
- Oracle XE
-
- SpringBoot-starter
web
session-core
session-jdbc
HikariCP
SpringSessionJdbc所需的库依赖已在附录的maven(pom.xml)中进行了记录。对于版本进行了缩写的库,将使用由SpringBoot2.0.5管理的版本。
备齐。
需要在SpringSession中使用数据库的必需物品
根据Maven的指示(pom.xml),需要至少具备以下基本要求。
-
- spring-boot-starter
web
session-core
session-jdbc
接続プール (今回はSpringBoot2から推奨されている HikariCP を利用しています)
設定ファイルにデータベース接続プールの設定と、SpringSessionの設定を記載
用于使用的Config类
将@EnableJdbcHttpSession声明在SpringBoot中创建应用程序时常常在Configure类中创建。如果应用程序中没有JDBC设置,则可以编写JDBC事务设置。以下是JavaConfig的示例。
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.session.jdbc.config.annotation.web.http.EnableJdbcHttpSession;
import org.springframework.transaction.PlatformTransactionManager;
/**
* @author A-pZ
*/
@EnableJdbcHttpSession
public class JdbcHttpSessionConfig {
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
JDBC的配置
请参考附录中的设置(application.yml)来配置JDBC。
使用HTTP会话的控制器
以下是一个使用HttpSession的控制器的具体示例。
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
/**
* @author A-pZ
*/
@Controller
public class SampleController {
@GetMapping("")
public String start(HttpSession session) {
session.setAttribute("sample", "sample");
return "index";
}
}
执行此Controller后,将输出一个静态HTML的Thymeleaf模板(也可以是JSP)的页面(index.html),在这个页面上不做任何特殊操作。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
</head>
<body>
index.html
</body>
</html>
動作後,查看正在處理的會話所使用的數據庫記錄。

从这种情况我们可以得出,会话信息已存储在数据库中。
附录
Maven(pom.xml)
请将Oracle JDBC驱动程序注册到独立的本地存储库,或注册到本地环境中的Nexus等存储库。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.github.alphapz.springsample</groupId>
<artifactId>spring-session-sample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>spring-session-sample</name>
<description>spring-session-sample</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.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>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>oracle.jdbc</groupId>
<artifactId>ojdbc7</artifactId>
<version>12.1.0.2.0</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
設置(application.yml)
这是使SpringSessionJdbc运行所需的最基本配置。
spring:
session:
timeout: 300
jdbc:
initialize-schema: always
table-name: SPRING_SESSION
datasource:
url: jdbc:oracle:thin:@127.0.0.1:1521:xe
username: springsession
password: springsession
tomcat:
data-source: com.zaxxer.hikari.HikariDataSource
在Oracle数据库中使用SQL投入。
CREATE TABLE SPRING_SESSION (
PRIMARY_ID CHAR(36) NOT NULL,
SESSION_ID CHAR(36) NOT NULL,
CREATION_TIME NUMBER(19,0) NOT NULL,
LAST_ACCESS_TIME NUMBER(19,0) NOT NULL,
MAX_INACTIVE_INTERVAL NUMBER(10,0) NOT NULL,
EXPIRY_TIME NUMBER(19,0) NOT NULL,
PRINCIPAL_NAME VARCHAR2(100 CHAR),
CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (PRIMARY_ID)
);
CREATE UNIQUE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (SESSION_ID);
CREATE INDEX SPRING_SESSION_IX2 ON SPRING_SESSION (EXPIRY_TIME);
CREATE INDEX SPRING_SESSION_IX3 ON SPRING_SESSION (PRINCIPAL_NAME);
CREATE TABLE SPRING_SESSION_ATTRIBUTES (
SESSION_PRIMARY_ID CHAR(36) NOT NULL,
ATTRIBUTE_NAME VARCHAR2(200 CHAR) NOT NULL,
ATTRIBUTE_BYTES BLOB NOT NULL,
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_PRIMARY_ID, ATTRIBUTE_NAME),
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_PRIMARY_ID) REFERENCES SPRING_SESSION(PRIMARY_ID) ON DELETE CASCADE
);
沉迷的要点 (Chen mi de yao dian)
要启用JDBC使用的SpringSession,实际上需要设置的地方减少了很多,只需要通过@EnableJdbcHttpSession注解传递必要的SpringBean定义,这些定义只需从TransactionManager传递DataSource即可。
实际上,在使用某种JavaConfig来配置DataSource时,如果不给Bean设置优先级或者使用Qualifier为其命名别名,则会在启动时发生错误。此外,如果使用旧版的Spring Boot来进行DataSource配置,则由于DataSource的配置方式已经发生变化,同样会导致运行时错误。(例如,无法解析数据源类型,或者无法将其从yml文件中读取并转换为相应类型等等…)