Spring Session的使用示例

网友投稿 845 2023-01-08

Spring Session的使用示例

Spring Session的使用示例

目录SessionSession常用解决方案Spring-Session测试代码基于数据库的Spring-Session基于Redis的Spring-Session总结

Session

Http协议是无状态的,这样对于服务端来说,没有办法区分是新的访客还是旧的访客。但是,有些业务场景,需要追踪用户多个请求,此时就需要Session。关于session的百度百科session

Session:在计算机中,尤其是在网络应用中,称为“会话控制”。Session对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的Web页之间跳转时,存储在Session对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当用户请求来自应用程序的 Web页时,如果该用户还没有会话,则Web服务器将自动创建一个 Session对象。当会话过期或被放弃后,服务器将终止该会话

核心特点:

服务端存储

会过期

Session常用解决方案

对于Session的常用解决方案,可以划分为三种。

负载均衡方式

借助负载均衡设备或者模块,将指定的Session始终路由到同一台机器即可,如Nginx。

副本复制方式

利用服务器节点间的副本复制方式,保证集群所有节点拥有的Session数据一致。

集中存储方式

引入第三方存储,将Session数据集中存储到外部存储中,如Redis或者数据库等。

本文介绍的Spring-Session是采用第三种,集中存储的方式。

Spring-Session

核心组成模块

Spring Session Core

提供Spring Session核心的功能和API

Spring Session Data Redis

提供基于Redis的SessionRepository以及配置

Spring Session JDBC

提供基于关系型数据库的SessionRepository以及配置

Spring Session Hazelcast

提供基于Hazelcast的SessionRepository以及配置

测试代码

controller提供三个接口,分别对应Session的获取、保存和清理

@GetMapping("/")

public String process(Model model, HttpSession session) {

@SuppressWarnings("unchecked")

List messages = (List) session.getAttribute("springSession");

if (messages == null) {

messages = new ArrayList<>();

}

model.addAttribute("sessionMessages", messages);

return "sessionTest";

}

@PostMapping("/persistSession")

public String persistMessage(@RequestParam("msg") String msg, HttpServletRequest request) {

@SuppressWarnings("unchecked")

List messages = (List) request.getSession().getAttribute("springSession");

if (messages == null) {

messages = new ArrayList<>();

request.getSession().setAttribute("springSession", messages);

}

messages.add(msg);

request.getSession().setAttribute("springSession", messages);

return "redirect:/";

}

@PostMapping("/destroySession")

public String destroySession(HttpServletRequest request) {

request.getSession().invalidate();

return "redirect:/";

}

sessionTest.html对应页面操作


基于数据库的Spring-Session

1.引入maven依赖

使用mysql存储,所以引入了MySQL。

涉及到SpringBoot JDBC的配置,引入了Spring Boot JDBC Starter。

org.springframework.session

spring-session-core

2.5.0

org.springframework.session

spring-session-jdbc

2.5.0

mysql

mysql-connector-java

8.0.18

org.springframework.boot

spring-boot-starter-jdbc

注意:

No session repository could be auto-configured, check your configuration (session store type is 'jdbc')

如果存在这个报错,是因为没有引入spring-boot-starter-jdbc,引入即可。

2.配置application.properties文件

主要包含两部分,数据库的配置以及Spring Session Jdbc配置。

# 配置数据源相关内容

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

spring.datasource.url=jdbc:mysql://127.0.0.1:3306/spring_learn?createDatabaseIfNotExist=true&autoReconnect=true&useSSL=false

spring.datasource.username=xxx

spring.datasource.password=xxx

spring.datasource.initialization-mode=always

# session类型选择jdbc

spring.session.store-type=jdbc

spring.session.jdbc.initialize-schema=always

# 指定表名

#spring.session.jdbc.table-name=SESSIONS

# 超时时间

spring.session.timeout=180s

3.数据库存储解析

默认情况下,数据库中会创建2张表。SPRING_SESSION和SPRING_SESSION_ATTRIBUTION。

SPRING_SESSION用于存在session自身的一些属性,如创建时间、过期时间等,详细schema如下。

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) DEFAULT NULL,

PRIMARY KEY (`PRIMARY_ID`),

UNIQUE KEY `SPRING_SESSION_IX1` (`SESSION_ID`),

KEY `SPRING_SESSION_IX2` (`EXPIRY_TIME`),

KEY `SPRING_SESSION_IX3` (`PRINCIPAL_NAME`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC

SPRING_SESSION_ATTRIBUTION用于存储session相关联的属性,schema如下。

CREATE TABLE `SPRING_SESSION_ATTRIBUTES` (

`SESSION_PRIMARY_ID` char(36) NOT NULL,

`ATTRIBUTE_NAME` varchar(200) NOT NULL,

`ATTRIBUTE_BYTES` blob NOT NULL,

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 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC

4.测试执行

SPRING_SESSION中的数据

SPRING_SESSION_ATTRIBUTION中的数据。

基于Redis的Spring-Session

几乎同样的步骤

maven依赖

org.springframework.boovAHTCt

spring-boot-starter-data-redis

org.springframework.session

spring-session-data-redis

application.properties配置

spring.session.store-type=redis

spring.redis.host=127.0.0.1

spring.redis.port=6379

结果分析

一次请求后,多了三个属性,分析如下。

key

类型

用途

value

spring:session:sessions:expires:${sessionId}

string

判断sesssion是否存在

spring:session:sessions:${sessionId}

hash

session相关的属性,包括有效期、创建时间、具体属性等

creationTime/lastAccessedTime/sessionAttr/maxInactiveInterval

spring:session:expirations:1623656160000

set

存储待过期的sessionId列表

key: 过期的时间戳;value: 在这个时间戳将要过期的expire key列表。

在访问时,先通过第一个key,判断session是否存在以及是否过期。如果没有过期,可以通过第二个key获取或者更新对应的session详情。

对于第三个key,实际上Spring-Session-Redis会有特殊的用途,主要是为了Redis的keySpace-notificationhttps://redis.io/topics/notifications。核心目的是为了确保过期的session一定要触发过期事件。关于这方面的解释,可以看一下RedisIndexedSessionRepository中的注释。

订阅Spring-Session的相关事件

有些时候,我们比较关心Session的创建或者销毁事件,做一些特殊的处理或者记录。基于Redis的Spring-Session利用Spring Event将该事件发布出来,我们可以使用EventListener监听做处理。

@Component

@Slf4j

public class AnnotationDrivenEventListener {

@EventListener

public void handleSessionCreated(SessionCreatedEvent sessionCreatedEvent) {

String sessionId = sessionCreatedEvent.getSessionId();

log.info("session id:{} created", sessionId);

}

@EventListener

public void handleSessionDestroyed(SessionDestroyedEvent sessionDestroyedEvent) {

String sessionId = sessionDestroyedEvent.getSessionId();

log.info("session id:{} destroyed", sessionId);

}

}

总结

Spring Session提供了非常便利的,基于关系型数据库或者Redis的Session解决方案。

Redis版访问速度快,基于Redis的过期策略,保证过期数据会被删除,同时支持事件订阅。

数据库版直接基于数据库,无需单独引入其他存储。但是访问速度相对较慢,过期数据需要依赖应用程序自身进行删除。同时没有提供事件订阅能力。

以上就是Spring Session的使用示例的详细内容,更多关于Spring Session的使用的资料请关注我们其它相关文章!

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:金融小程序页面设计图(金融小程序页面设计图案)
下一篇:小程序生态搜索(微信小程序开发搜索)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~