2021-01-02 04:00:49 +08:00
|
|
|
|
# Session会话
|
2020-02-06 00:52:49 +08:00
|
|
|
|
---
|
|
|
|
|
|
2021-02-06 13:51:30 +08:00
|
|
|
|
### Session是什么?
|
|
|
|
|
|
|
|
|
|
Session是会话中专业的数据缓存组件,通过`Session`我们可以很方便的缓存一些高频读写数据,提高程序性能<br>
|
|
|
|
|
在`sa-token`中, `Session` 分为三种, 分别是:
|
2021-01-31 23:28:42 +08:00
|
|
|
|
- `User-Session`: 指的是框架为每个`loginId`分配的`Session`
|
|
|
|
|
- `Token-Session`: 指的是框架为每个`token`分配的`Session`
|
2021-01-02 04:00:49 +08:00
|
|
|
|
- `自定义Session`: 指的是以一个`特定的值`作为SessionId,来分配的`Session`
|
2020-02-06 00:52:49 +08:00
|
|
|
|
|
2021-03-11 01:06:27 +08:00
|
|
|
|
> 有关User-Session与Token-Session的详细区别,请参考:[Session模型详解](/fun/session-model)
|
|
|
|
|
|
2020-02-06 00:52:49 +08:00
|
|
|
|
|
2021-01-31 23:28:42 +08:00
|
|
|
|
### User-Session
|
2021-01-02 04:00:49 +08:00
|
|
|
|
有关账号Session的API如下:
|
|
|
|
|
``` java
|
2021-01-31 23:28:42 +08:00
|
|
|
|
// 获取当前账号id的Session (必须是登录后才能调用)
|
|
|
|
|
StpUtil.getSession();
|
|
|
|
|
|
|
|
|
|
// 获取当前账号id的Session, 并决定在Session尚未创建时,是否新建并返回
|
|
|
|
|
StpUtil.getSession(true);
|
|
|
|
|
|
|
|
|
|
// 获取账号id为10001的Session
|
|
|
|
|
StpUtil.getSessionByLoginId(10001);
|
|
|
|
|
|
|
|
|
|
// 获取账号id为10001的Session, 并决定在Session尚未创建时,是否新建并返回
|
|
|
|
|
StpUtil.getSessionByLoginId(10001, true);
|
|
|
|
|
|
|
|
|
|
// 获取SessionId为xxxx-xxxx的Session, 在Session尚未创建时, 返回null
|
|
|
|
|
StpUtil.getSessionBySessionId("xxxx-xxxx");
|
2021-01-02 04:00:49 +08:00
|
|
|
|
```
|
2020-02-06 00:52:49 +08:00
|
|
|
|
|
|
|
|
|
|
2021-01-31 23:28:42 +08:00
|
|
|
|
### Token-Session
|
2021-01-02 04:00:49 +08:00
|
|
|
|
有关令牌Session的API如下:
|
|
|
|
|
``` java
|
2021-01-31 23:28:42 +08:00
|
|
|
|
// 获取当前token的专属Session
|
|
|
|
|
StpUtil.getTokenSession();
|
|
|
|
|
|
|
|
|
|
// 获取指定token的专属Session
|
|
|
|
|
StpUtil.getTokenSessionByToken(token);
|
2021-01-02 04:00:49 +08:00
|
|
|
|
```
|
2021-01-31 23:28:42 +08:00
|
|
|
|
在未登录状态下是否可以获取`Token-Session`?这取决于你配置的`tokenSessionCheckLogin`值是否为false,详见:[框架配置](/use/config?id=所有可配置项)
|
2020-02-06 00:52:49 +08:00
|
|
|
|
|
|
|
|
|
|
2021-01-31 23:28:42 +08:00
|
|
|
|
### 自定义Session
|
2021-01-02 04:00:49 +08:00
|
|
|
|
自定义Session指的是以一个`特定的值`作为SessionId来分配的`Session`, 借助自定义Session,你可以为系统中的任意元素分配相应的session<br>
|
|
|
|
|
例如以商品id作为key为每个商品分配一个Session,以便于缓存和商品相关的数据,其相关API如下:
|
|
|
|
|
``` java
|
2021-01-31 23:28:42 +08:00
|
|
|
|
// 查询指定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");
|
2021-01-02 04:00:49 +08:00
|
|
|
|
```
|
2020-02-06 00:52:49 +08:00
|
|
|
|
|
|
|
|
|
|
2021-01-31 23:28:42 +08:00
|
|
|
|
### Session相关操作
|
2020-02-06 00:52:49 +08:00
|
|
|
|
那么获取到的`SaSession`具体有哪些方法可供操作?
|
2021-01-02 04:00:49 +08:00
|
|
|
|
``` java
|
2021-03-23 02:24:37 +08:00
|
|
|
|
// 返回此Session的id
|
|
|
|
|
session.getId();
|
|
|
|
|
|
|
|
|
|
// 返回此Session的创建时间 (时间戳)
|
|
|
|
|
session.getCreateTime();
|
|
|
|
|
|
|
|
|
|
// 在Session上获取一个值
|
|
|
|
|
session.getAttribute('name');
|
|
|
|
|
|
|
|
|
|
// 在Session上获取一个值,并指定取不到值时返回的默认值
|
|
|
|
|
session.getAttribute('name', 'zhang');
|
|
|
|
|
|
|
|
|
|
// 在Session上写入一个值
|
|
|
|
|
session.setAttribute('name', 'zhang');
|
|
|
|
|
|
|
|
|
|
// 在Session上移除一个值
|
|
|
|
|
session.removeAttribute('name');
|
|
|
|
|
|
|
|
|
|
// 清空此Session的所有值
|
|
|
|
|
session.clearAttribute();
|
|
|
|
|
|
|
|
|
|
// 获取此Session是否含有指定key (返回true或false)
|
|
|
|
|
session.containsAttribute('name');
|
|
|
|
|
|
|
|
|
|
// 获取此Session会话上所有key (返回Set<String>)
|
|
|
|
|
session.attributeKeys();
|
|
|
|
|
|
|
|
|
|
// 返回此Session会话上的底层数据对象(如果更新map里的值,请调用session.update()方法避免产生脏数据)
|
|
|
|
|
session.getDataMap();
|
|
|
|
|
|
|
|
|
|
// 将这个Session从持久库更新一下
|
|
|
|
|
session.update();
|
|
|
|
|
|
|
|
|
|
// 注销此Session会话 (从持久库删除此Session)
|
|
|
|
|
session.logout();
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 类型转换API
|
|
|
|
|
由于Session存取值默认的类型都是Object,因此我们通常会写很多不必要类型转换代码 <br>
|
|
|
|
|
为了简化操作,sa-token自`v1.15.0`封装了存取值API的类型转换,你可以非常方便的调用以下方法:
|
|
|
|
|
``` java
|
|
|
|
|
// 写值
|
|
|
|
|
session.set("name", "zhang");
|
|
|
|
|
|
2021-04-30 23:48:12 +08:00
|
|
|
|
// 写值 (只有在此key原本无值的时候才会写入)
|
|
|
|
|
session.setDefaultValue("name", "zhang");
|
2021-03-23 02:24:37 +08:00
|
|
|
|
|
|
|
|
|
// 取值
|
|
|
|
|
session.get("name");
|
|
|
|
|
|
|
|
|
|
// 取值 (指定默认值)
|
|
|
|
|
session.get("name", "<defaultValue>");
|
|
|
|
|
|
|
|
|
|
// 取值 (转String类型)
|
|
|
|
|
session.getString("name");
|
|
|
|
|
|
|
|
|
|
// 取值 (转int类型)
|
|
|
|
|
session.getInt("age");
|
|
|
|
|
|
|
|
|
|
// 取值 (转long类型)
|
|
|
|
|
session.getLong("age");
|
|
|
|
|
|
|
|
|
|
// 取值 (转double类型)
|
|
|
|
|
session.getDouble("result");
|
|
|
|
|
|
|
|
|
|
// 取值 (转float类型)
|
|
|
|
|
session.getFloat("result");
|
|
|
|
|
|
|
|
|
|
// 取值 (指定转换类型)
|
|
|
|
|
session.getModel("key", Student.class);
|
|
|
|
|
|
|
|
|
|
// 取值 (指定转换类型, 并指定值为Null时返回的默认值)
|
|
|
|
|
session.getModel("key", Student.class, <defaultValue>);
|
|
|
|
|
|
|
|
|
|
// 是否含有某个key
|
|
|
|
|
session.has("key");
|
2021-01-02 04:00:49 +08:00
|
|
|
|
```
|
2020-02-06 00:52:49 +08:00
|
|
|
|
|
|
|
|
|
|
2021-03-16 16:13:39 +08:00
|
|
|
|
### Session环境隔离说明
|
2021-03-23 02:24:37 +08:00
|
|
|
|
有同学经常会把 `SaSession` 与 `HttpSession` 进行混淆,例如:
|
2021-03-16 16:13:39 +08:00
|
|
|
|
``` java
|
|
|
|
|
@PostMapping("/resetPoints")
|
|
|
|
|
public void reset(HttpSession session) {
|
2021-03-23 02:24:37 +08:00
|
|
|
|
// 在HttpSession上写入一个值
|
|
|
|
|
session.setAttribute("name", 66);
|
|
|
|
|
// 在SaSession进行取值
|
|
|
|
|
System.out.println(StpUtil.getSession().getAttribute("name")); // 输出null
|
2021-03-16 16:13:39 +08:00
|
|
|
|
}
|
|
|
|
|
```
|
2021-03-23 02:24:37 +08:00
|
|
|
|
**要点:**
|
|
|
|
|
1. `SaSession` 与 `HttpSession` 没有任何关系,在`HttpSession`上写入的值,在`SaSession`中无法取出
|
|
|
|
|
2. `HttpSession`并未被框架接管,在使用sa-token时,请在任何情况下均使用`SaSession`,不要使用`HttpSession`
|
2021-04-13 15:37:35 +08:00
|
|
|
|
|