在本文中,我们将了解如何将Spring Session与JDBC结合使用。 Spring Session 提供了一种解决HTTP会话限制的透明方法。它提供中央会话管理,而不依赖于特定于容器的解决方案(例如Tomcat,Jetty等)。它提供了存储和管理会话信息的不同选项。在本文中,我们将介绍将 JDBC与Spring Session集成的步骤。
如果您使用的是Spring Boot,则需要在应用程序的pom.xml文件中添加以下依赖项:
<dependencies>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-jdbc</artifactId>
</dependency>
<!-- Adding <b>this</b> to have datasource and other feature available to us -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
我们不需要为Spring会话添加依赖项,因为Spring Boot会对此进行处理。基于以上配置, Spring Boot自动配置 将为我们处理其余配置。作为最后一步,我们需要通知Spring Boot使用jdbc来存储会话信息。在application.properties文件中添加以下属性:
spring.session.store-type=jdbc # Session store type.
如果您只使用单个会话模块,则可以从application.properties文件中省略上述属性。Spring Boot自动使用该存储实现。如果您有多个实现,则必须指定上述属性。
在我们使用JDBC支持的spring会话之前,我们需要在应用程序中添加一些属性。属性文件:
spring.datasource.url=jdbc:mysql:<font><i>//localhost:3306/spring-session-jdbc</i></font><font> spring.datasource.username=root spring.datasource.password= spring.datasource.driver-<b>class</b>-name=com.mysql.cj.jdbc.Driver </font>
为了使Spring会话能够使用我们的JDBC配置,它需要在DB中创建某个表,我们可以通过以下属性启用此功能:
spring.session.jdbc.initialize-schema=always
一旦我们启用这些属性如果我们指定spring.session.jdbc.initialize-schema=never,那么我们需要手动创建会话表。Spring会话JDBC jar包含用于创建所需模式的SQL脚本。您可以在org.springframework.session.jdbc包下看到。
MySQL数据库存储会话的模式:
CREATE TABLE SPRING_SESSION (
PRIMARY_ID CHAR(36) NOT NULL,
SESSION_ID CHAR(36) NOT NULL,
CREATION_TIME BIGINT NOT NULL,
LAST_ACCESS_TIME BIGINT NOT NULL,
MAX_INACTIVE_INTERVAL INT NOT NULL,
EXPIRY_TIME BIGINT NOT NULL,
PRINCIPAL_NAME VARCHAR(100),
CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (PRIMARY_ID)
) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
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 VARCHAR(200) 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
) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
Spring JDBC Session和@EnableJdbcHttpSession
如果您使用 @EnableJdbcHttpSession,以上配置将无法正常工作。spring.session.*不适合你的原因是因为你正在使用@EnableJdbcHttpSession。
这意味着我们正在明确自己来配置Spring Session,因此Spring Boot的自动配置会不起作用。为了处理这个情况,我们有以下两个选项:
REST控制器
让我们创建一个简单的REST控制器来查看运行中的会话处理:
@RestController
<b>public</b> <b>class</b> GreetingController {
@GetMapping(<font>"/"</font><font>)
<b>public</b> @ResponseBody ResponseEntity<List> getMessage(Model model, HttpSession session) {
List greetings = (List) session.getAttribute(</font><font>"GREETING_MESSAGES"</font><font>);
<b>if</b>(greetings == <b>null</b>) {
greetings = <b>new</b> ArrayList<>();
}
<b>return</b> <b>new</b> ResponseEntity<List>(greetings,HttpStatus.OK);
}
@PostMapping(</font><font>"/messages"</font><font>)
<b>public</b> @ResponseBody ResponseEntity<List> saveMessage(@RequestParam(</font><font>"message"</font><font>) String greeting, HttpServletRequest request)
{
List greetings = (List) request.getSession().getAttribute(</font><font>"GREETING_MESSAGES"</font><font>);
<b>if</b>(greetings == <b>null</b>) {
greetings = <b>new</b> ArrayList<>();
request.getSession().setAttribute(</font><font>"GREETING_MESSAGES"</font><font>, greetings);
}
greetings.add(greeting);
<b>return</b> <b>new</b> ResponseEntity<List>(greetings,HttpStatus.OK);
}
}
</font>
Spring Boot主类:
@SpringBootApplication
@EnableJdbcHttpSession
<b>public</b> <b>class</b> SpringSessionWithJdbcApplication {
<b>public</b> <b>static</b> <b>void</b> main(String[] args) {
SpringApplication.run(SpringSessionWithJdbcApplication.<b>class</b>, args);
}
}
@EnableJdbcHttpSession注释创建一个名为的Spring bean springSessionRepositoryFilter实现Filter。过滤器负责替换由Spring Session支持的HttpSession实现。