sa-token/sa-token-doc/use/session.md
2023-06-21 23:10:29 +08:00

182 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Session会话
---
### 1、Session是什么
Session 是会话中专业的数据缓存组件,通过 Session 我们可以很方便的缓存一些高频读写数据,提高程序性能,例如:
``` java
// 在登录时缓存 user 对象
StpUtil.getSession().set("user", user);
// 然后我们就可以在任意处使用这个 user 对象
SysUser user = (SysUser) StpUtil.getSession().get("user");
```
在 Sa-Token 中Session 分为三种,分别是:
- `Account-Session`: 指的是框架为每个 账号id 分配的 Session
- `Token-Session`: 指的是框架为每个 token 分配的 Session
- `Custom-Session`: 指的是以一个 特定的值 作为SessionId来分配的 Session
> 有关 Account-Session 与 Token-Session 的详细区别,可参考:[Session模型详解](/fun/session-model)
### Account-Session
有关 账号-Session 的 API 如下:
``` java
// 获取当前账号 id 的 Account-Session (必须是登录后才能调用)
StpUtil.getSession();
// 获取当前账号 id 的 Account-Session, 并决定在 Session 尚未创建时,是否新建并返回
StpUtil.getSession(true);
// 获取账号 id 为 10001 的 Account-Session
StpUtil.getSessionByLoginId(10001);
// 获取账号 id 为 10001 的 Account-Session, 并决定在 Session 尚未创建时,是否新建并返回
StpUtil.getSessionByLoginId(10001, true);
// 获取 SessionId 为 xxxx-xxxx 的 Account-Session, 在 Session 尚未创建时, 返回 null
StpUtil.getSessionBySessionId("xxxx-xxxx");
```
### Token-Session
有关 令牌-Session 的 API 如下:
``` java
// 获取当前 Token 的 Token-Session 对象
StpUtil.getTokenSession();
// 获取指定 Token 的 Token-Session 对象
StpUtil.getTokenSessionByToken(token);
```
### Custom-Session
自定义 Session 指的是以一个`特定的值`作为 SessionId 来分配的`Session`, 借助自定义Session你可以为系统中的任意元素分配相应的session<br>
例如以商品 id 作为 key 为每个商品分配一个Session以便于缓存和商品相关的数据其相关API如下
``` java
// 查询指定key的Session是否存在
SaSessionCustomUtil.isExists("goods-10001");
// 获取指定key的Session如果没有则新建并返回
SaSessionCustomUtil.getSessionById("goods-10001");
// 获取指定key的Session如果没有第二个参数决定是否新建并返回
SaSessionCustomUtil.getSessionById("goods-10001", false);
// 删除指定key的Session
SaSessionCustomUtil.deleteSessionById("goods-10001");
```
### 在 Session 上存取值
以上三种 Session 均为框架设计概念上的区分,实际上在获取它们时,返回的都是 SaSession 对象,你可以使用以下 API 在 SaSession 对象上存取值:
``` java
// 写值
session.set("name", "zhang");
// 写值 (只有在此key原本无值的时候才会写入)
session.setDefaultValue("name", "zhang");
// 取值
session.get("name");
// 取值 (指定默认值)
session.get("name", "<defaultValue>");
// 取值 (若无值则执行参数方法, 之后将结果保存到此键名下,并返回此结果 若有值则直接返回, 无需执行参数方法)
session.get("name", () -> {
return ...;
});
// ---------- 数据类型转换: ----------
session.getInt("age"); // 取值 (转int类型)
session.getLong("age"); // 取值 (转long类型)
session.getString("name"); // 取值 (转String类型)
session.getDouble("result"); // 取值 (转double类型)
session.getFloat("result"); // 取值 (转float类型)
session.getModel("key", Student.class); // 取值 (指定转换类型)
session.getModel("key", Student.class, <defaultValue>); // 取值 (指定转换类型, 并指定值为Null时返回的默认值)
// 是否含有某个key (返回 true 或 false)
session.has("key");
// 删值
session.delete('name');
// 清空所有值
session.clear();
// 获取此 Session 的所有key (返回Set<String>)
session.keys();
```
### 其它操作
``` java
// 返回此 Session 的id
session.getId();
// 返回此 Session 的创建时间 (时间戳)
session.getCreateTime();
// 返回此 Session 会话上的底层数据对象如果更新map里的值请调用session.update()方法避免产生脏数据)
session.getDataMap();
// 将这个 Session 从持久库更新一下
session.update();
// 注销此 Session 会话 (从持久库删除此Session)
session.logout();
```
### 避免与 HttpSession 混淆使用
经常有同学会把 `SaSession``HttpSession` 进行混淆,例如:
``` java
@PostMapping("/resetPoints")
public void reset(HttpSession session) {
// 在 HttpSession 上写入一个值
session.setAttribute("name", 66);
// 在 SaSession 进行取值
System.out.println(StpUtil.getSession().get("name")); // 输出null
}
```
**要点:**
1. `SaSession` 与 `HttpSession` 没有任何关系,在`HttpSession`上写入的值,在`SaSession`中无法取出
2. `HttpSession`并未被框架接管在使用Sa-Token时请在任何情况下均使用`SaSession`,不要使用`HttpSession`
### 未登录场景下获取 Token-Session
默认场景下,只有登录后才能通过 `StpUtil.getTokenSession()` 获取 `Token-Session`。
如果想要在未登录场景下获取 Token-Session ,有两种方法:
- 方法一:将全局配置项 `tokenSessionCheckLogin` 改为 false详见[框架配置](/use/config?id=所有可配置项)
- 方法二:使用匿名 Token-Session
``` java
// 获取当前 Token 的匿名 Token-Session (可在未登录情况下使用的 Token-Session
StpUtil.getAnonTokenSession();
```
注意点:如果前端没有提交 Token ,或者提交的 Token 是一个无效 Token 的话,框架将不会根据此 Token 创建 `Token-Session` 对象,
而是随机一个新的 Token 值来创建 `Token-Session` 对象,此 Token 值可以通过 `StpUtil.getTokenValue()` 获取到。
---
<a class="case-btn" href="https://gitee.com/dromara/sa-token/blob/master/sa-token-demo/sa-token-demo-case/src/main/java/com/pj/cases/use/SaSessionController.java"
target="_blank">
本章代码示例Sa-Token Session 会话 —— [ com.pj.cases.use.SaSessionController.java ]
</a>
<a class="dt-btn" href="https://www.wenjuan.ltd/s/MNnUr2V/" target="_blank">本章小练习Sa-Token 基础 - Session 会话,章节测试</a>