在本文中,我们将了解如何将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实现。