mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-09-20 18:47:58 +08:00
v1.10.0新特性:查询所有会话
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
package cn.dev33.satoken.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import cn.dev33.satoken.session.SaSession;
|
||||
|
||||
/**
|
||||
@@ -8,14 +10,14 @@ import cn.dev33.satoken.session.SaSession;
|
||||
*/
|
||||
public interface SaTokenDao {
|
||||
|
||||
|
||||
/** 常量,表示一个key永不过期 (在一个key被标注为永远不过期时返回此值) */
|
||||
public static final Long NEVER_EXPIRE = -1L;
|
||||
|
||||
/** 常量,表示系统中不存在这个缓存 (在对不存在的key获取剩余存活时间时返回此值) */
|
||||
public static final Long NOT_VALUE_EXPIRE = -2L;
|
||||
|
||||
|
||||
|
||||
// --------------------- token相关 ---------------------
|
||||
|
||||
/**
|
||||
* 根据key获取value,如果没有,则返回空
|
||||
@@ -58,7 +60,9 @@ public interface SaTokenDao {
|
||||
* @param timeout 过期时间
|
||||
*/
|
||||
public void updateTimeout(String key, long timeout);
|
||||
|
||||
|
||||
// --------------------- Session相关 ---------------------
|
||||
|
||||
/**
|
||||
* 根据指定key的Session,如果没有,则返回空
|
||||
@@ -101,7 +105,17 @@ public interface SaTokenDao {
|
||||
public void updateSessionTimeout(String sessionId, long timeout);
|
||||
|
||||
|
||||
|
||||
// --------------------- 会话管理 ---------------------
|
||||
|
||||
/**
|
||||
* 搜索数据
|
||||
* @param prefix 前缀
|
||||
* @param keyword 关键字
|
||||
* @param start 开始处索引 (-1代表查询所有)
|
||||
* @param size 获取数量
|
||||
* @return sessionId集合
|
||||
*/
|
||||
public List<String> searchData(String prefix, String keyword, int start, int size);
|
||||
|
||||
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@ package cn.dev33.satoken.dao;
|
||||
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Timer;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -10,6 +11,7 @@ import cn.dev33.satoken.SaTokenManager;
|
||||
import cn.dev33.satoken.session.SaSession;
|
||||
import cn.dev33.satoken.util.SaTaskUtil;
|
||||
import cn.dev33.satoken.util.SaTaskUtil.FunctionRunClass;
|
||||
import cn.dev33.satoken.util.SaTokenInsideUtil;
|
||||
|
||||
/**
|
||||
* sa-token持久层默认的实现类 , 基于内存Map
|
||||
@@ -207,6 +209,14 @@ public class SaTokenDaoDefaultImpl implements SaTokenDao {
|
||||
|
||||
|
||||
|
||||
// --------------------- 会话管理
|
||||
|
||||
@Override
|
||||
public List<String> searchData(String prefix, String keyword, int start, int size) {
|
||||
return SaTokenInsideUtil.searchList(expireMap.keySet(), prefix, keyword, start, size);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -202,7 +202,6 @@ public class StpLogic {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 当前会话注销登录
|
||||
*/
|
||||
@@ -219,7 +218,6 @@ public class StpLogic {
|
||||
logoutByTokenValue(tokenValue);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 指定token的会话注销登录
|
||||
* @param tokenValue 指定token
|
||||
@@ -246,7 +244,6 @@ public class StpLogic {
|
||||
session.logoutByTokenSignCountToZero();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 指定loginId的会话注销登录(踢人下线)
|
||||
* <p> 当对方再次访问系统时,会抛出NotLoginException异常,场景值=-2
|
||||
@@ -287,7 +284,6 @@ public class StpLogic {
|
||||
session.logoutByTokenSignCountToZero();
|
||||
}
|
||||
|
||||
|
||||
// 查询相关
|
||||
|
||||
/**
|
||||
@@ -299,7 +295,6 @@ public class StpLogic {
|
||||
return getLoginIdDefaultNull() != null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 检验当前会话是否已经登录,如未登录,则抛出异常
|
||||
*/
|
||||
@@ -307,7 +302,6 @@ public class StpLogic {
|
||||
getLoginId();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前会话账号id, 如果未登录,则抛出异常
|
||||
* @return 账号id
|
||||
@@ -342,7 +336,6 @@ public class StpLogic {
|
||||
return loginId;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前会话登录id, 如果未登录,则返回默认值
|
||||
* @param <T> 返回类型
|
||||
@@ -369,7 +362,6 @@ public class StpLogic {
|
||||
return (T)loginId;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前会话登录id, 如果未登录,则返回null
|
||||
* @return 账号id
|
||||
@@ -393,7 +385,6 @@ public class StpLogic {
|
||||
return loginId;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前会话登录id, 并转换为String
|
||||
* @return 账号id
|
||||
@@ -402,7 +393,6 @@ public class StpLogic {
|
||||
return String.valueOf(getLoginId());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前会话登录id, 并转换为int
|
||||
* @return 账号id
|
||||
@@ -415,7 +405,6 @@ public class StpLogic {
|
||||
return Integer.valueOf(String.valueOf(getLoginId()));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前会话登录id, 并转换为long
|
||||
* @return 账号id
|
||||
@@ -428,7 +417,6 @@ public class StpLogic {
|
||||
return Long.valueOf(String.valueOf(getLoginId()));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取指定token对应的登录id,如果未登录,则返回 null
|
||||
* @param tokenValue token
|
||||
@@ -462,6 +450,14 @@ public class StpLogic {
|
||||
return session;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定key的session, 如果session尚未创建,则返回null
|
||||
* @param sessionId sessionId
|
||||
* @return session对象
|
||||
*/
|
||||
public SaSession getSessionBySessionId(String sessionId) {
|
||||
return getSessionBySessionId(sessionId, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定loginId的session, 如果session尚未创建,isCreate=是否新建并返回
|
||||
@@ -473,7 +469,6 @@ public class StpLogic {
|
||||
return getSessionBySessionId(getKeySession(loginId), isCreate);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取指定loginId的session,如果session尚未创建,则新建并返回
|
||||
* @param loginId 账号id
|
||||
@@ -483,7 +478,6 @@ public class StpLogic {
|
||||
return getSessionByLoginId(loginId, true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前会话的session, 如果session尚未创建,isCreate=是否新建并返回
|
||||
* @param isCreate 是否新建
|
||||
@@ -493,7 +487,6 @@ public class StpLogic {
|
||||
return getSessionByLoginId(getLoginId(), isCreate);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前会话的session,如果session尚未创建,则新建并返回
|
||||
* @return 当前会话的session
|
||||
@@ -505,7 +498,6 @@ public class StpLogic {
|
||||
|
||||
// =================== token专属session ===================
|
||||
|
||||
|
||||
/**
|
||||
* 获取指定token的专属session,如果session尚未创建,isCreate代表是否新建并返回
|
||||
* @param tokenValue token值
|
||||
@@ -516,7 +508,6 @@ public class StpLogic {
|
||||
return getSessionBySessionId(getKeyTokenSession(tokenValue), isCreate);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取指定token的专属session,如果session尚未创建,则新建并返回
|
||||
* @param tokenValue token值
|
||||
@@ -526,7 +517,6 @@ public class StpLogic {
|
||||
return getSessionBySessionId(getKeyTokenSession(tokenValue), true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前token的专属-session,如果session尚未创建,isCreate代表是否新建并返回
|
||||
* @param isCreate 是否新建
|
||||
@@ -547,7 +537,6 @@ public class StpLogic {
|
||||
return getSessionBySessionId(getKeyTokenSession(getTokenValue()), isCreate);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前token的专属-session,如果session尚未创建,则新建并返回
|
||||
* @return session会话
|
||||
@@ -559,7 +548,6 @@ public class StpLogic {
|
||||
|
||||
// =================== [临时过期] 验证相关 ===================
|
||||
|
||||
|
||||
/**
|
||||
* 写入指定token的 [最后操作时间] 为当前时间戳
|
||||
* @param tokenValue 指定token
|
||||
@@ -573,7 +561,6 @@ public class StpLogic {
|
||||
SaTokenManager.getSaTokenDao().setValue(getKeyLastActivityTime(tokenValue), String.valueOf(System.currentTimeMillis()), getConfig().getTimeout());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 清除指定token的 [最后操作时间]
|
||||
* @param tokenValue 指定token
|
||||
@@ -589,7 +576,6 @@ public class StpLogic {
|
||||
SaTokenManager.getSaTokenServlet().getRequest().removeAttribute(SaTokenConsts.TOKEN_ACTIVITY_TIMEOUT_CHECKED_KEY);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 检查指定token 是否已经[临时过期],如果已经过期则抛出异常
|
||||
* @param tokenValue 指定token
|
||||
@@ -621,7 +607,6 @@ public class StpLogic {
|
||||
request.setAttribute(SaTokenConsts.TOKEN_ACTIVITY_TIMEOUT_CHECKED_KEY, true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 检查当前token 是否已经[临时过期],如果已经过期则抛出异常
|
||||
*/
|
||||
@@ -629,7 +614,6 @@ public class StpLogic {
|
||||
checkActivityTimeout(getTokenValue());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 续签指定token:(将 [最后操作时间] 更新为当前时间戳)
|
||||
* @param tokenValue 指定token
|
||||
@@ -642,7 +626,6 @@ public class StpLogic {
|
||||
SaTokenManager.getSaTokenDao().updateValue(getKeyLastActivityTime(tokenValue), String.valueOf(System.currentTimeMillis()));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 续签当前token:(将 [最后操作时间] 更新为当前时间戳)
|
||||
* <h1>请注意: 即时token已经 [临时过期] 也可续签成功,
|
||||
@@ -653,7 +636,6 @@ public class StpLogic {
|
||||
}
|
||||
|
||||
|
||||
|
||||
// =================== 过期时间相关 ===================
|
||||
|
||||
/**
|
||||
@@ -965,6 +947,42 @@ public class StpLogic {
|
||||
}
|
||||
|
||||
|
||||
// =================== 会话管理 ===================
|
||||
|
||||
/**
|
||||
* 根据条件查询token
|
||||
* @param keyword 关键字
|
||||
* @param start 开始处索引 (-1代表查询所有)
|
||||
* @param size 获取数量
|
||||
* @return token集合
|
||||
*/
|
||||
public List<String> searchTokenValue(String keyword, int start, int size) {
|
||||
return SaTokenManager.getSaTokenDao().searchData(getKeyTokenValue(""), keyword, start, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据条件查询SessionId
|
||||
* @param keyword 关键字
|
||||
* @param start 开始处索引 (-1代表查询所有)
|
||||
* @param size 获取数量
|
||||
* @return sessionId集合
|
||||
*/
|
||||
public List<String> searchSessionId(String keyword, int start, int size) {
|
||||
return SaTokenManager.getSaTokenDao().searchData(getKeySession(""), keyword, start, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据条件查询token专属Session的Id
|
||||
* @param keyword 关键字
|
||||
* @param start 开始处索引 (-1代表查询所有)
|
||||
* @param size 获取数量
|
||||
* @return sessionId集合
|
||||
*/
|
||||
public List<String> searchTokenSessionId(String keyword, int start, int size) {
|
||||
return SaTokenManager.getSaTokenDao().searchData(getKeyTokenSession(""), keyword, start, size);
|
||||
}
|
||||
|
||||
|
||||
// =================== 返回相应key ===================
|
||||
|
||||
/**
|
||||
|
@@ -194,6 +194,15 @@ public class StpUtil {
|
||||
return stpLogic.getSessionByLoginId(loginId, isCreate);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定key的session, 如果session尚未创建,则返回null
|
||||
* @param sessionId sessionId
|
||||
* @return session对象
|
||||
*/
|
||||
public static SaSession getSessionBySessionId(String sessionId) {
|
||||
return stpLogic.getSessionBySessionId(sessionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定loginId的session,如果session尚未创建,则新建并返回
|
||||
* @param loginId 账号id
|
||||
@@ -439,5 +448,42 @@ public class StpUtil {
|
||||
public static String getLoginDevice() {
|
||||
return stpLogic.getLoginDevice();
|
||||
}
|
||||
|
||||
|
||||
// =================== 会话管理 ===================
|
||||
|
||||
/**
|
||||
* 根据条件查询token
|
||||
* @param keyword 关键字
|
||||
* @param start 开始处索引 (-1代表查询所有)
|
||||
* @param size 获取数量
|
||||
* @return token集合
|
||||
*/
|
||||
public static List<String> searchTokenValue(String keyword, int start, int size) {
|
||||
return stpLogic.searchTokenValue(keyword, start, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据条件查询SessionId
|
||||
* @param keyword 关键字
|
||||
* @param start 开始处索引 (-1代表查询所有)
|
||||
* @param size 获取数量
|
||||
* @return sessionId集合
|
||||
*/
|
||||
public static List<String> searchSessionId(String keyword, int start, int size) {
|
||||
return stpLogic.searchSessionId(keyword, start, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据条件查询token专属Session的Id
|
||||
* @param keyword 关键字
|
||||
* @param start 开始处索引 (-1代表查询所有)
|
||||
* @param size 获取数量
|
||||
* @return sessionId集合
|
||||
*/
|
||||
public static List<String> searchTokenSessionId(String keyword, int start, int size) {
|
||||
return stpLogic.searchTokenSessionId(keyword, start, size);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -1,9 +1,13 @@
|
||||
package cn.dev33.satoken.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* sa-token 工具类
|
||||
* sa-token 内部代码工具类
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
@@ -49,4 +53,58 @@ public class SaTokenInsideUtil {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 从集合里查询数据
|
||||
* @param dataList 数据集合
|
||||
* @param prefix 前缀
|
||||
* @param keyword 关键字
|
||||
* @param start 起始位置 (-1代表查询所有)
|
||||
* @param size 获取条数
|
||||
* @return 符合条件的新数据集合
|
||||
*/
|
||||
public static List<String> searchList(Collection<String> dataList, String prefix, String keyword, int start, int size) {
|
||||
if(prefix == null) {
|
||||
prefix = "";
|
||||
}
|
||||
if(keyword == null) {
|
||||
keyword = "";
|
||||
}
|
||||
// 挑选出所有符合条件的
|
||||
List<String> list = new ArrayList<String>();
|
||||
Iterator<String> keys = dataList.iterator();
|
||||
while (keys.hasNext()) {
|
||||
String key = keys.next();
|
||||
if(key.startsWith(prefix) && key.indexOf(keyword) > -1) {
|
||||
list.add(key);
|
||||
}
|
||||
}
|
||||
// 取指定段数据
|
||||
return searchList(list, start, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从集合里查询数据
|
||||
* @param list 数据集合
|
||||
* @param start 起始位置 (-1代表查询所有)
|
||||
* @param size 获取条数
|
||||
* @return 符合条件的新数据集合
|
||||
*/
|
||||
public static List<String> searchList(List<String> list, int start, int size) {
|
||||
// 取指定段数据
|
||||
if(start < 0) {
|
||||
return list;
|
||||
}
|
||||
int end = start + size;
|
||||
List<String> list2 = new ArrayList<String>();
|
||||
for (int i = start; i < end; i++) {
|
||||
if(i >= list.size()) {
|
||||
return list2;
|
||||
}
|
||||
list2.add(list.get(i));
|
||||
}
|
||||
return list2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@@ -1,6 +1,9 @@
|
||||
package cn.dev33.satoken.dao;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -15,6 +18,7 @@ import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import cn.dev33.satoken.session.SaSession;
|
||||
import cn.dev33.satoken.util.SaTokenInsideUtil;
|
||||
|
||||
/**
|
||||
* sa-token持久层的实现类, 基于redis (to jackson)
|
||||
@@ -181,5 +185,15 @@ public class SaTokenDaoRedisJackson implements SaTokenDao {
|
||||
public void updateSessionTimeout(String sessionId, long timeout) {
|
||||
sessionRedisTemplate.expire(sessionId, timeout, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索数据
|
||||
*/
|
||||
@Override
|
||||
public List<String> searchData(String prefix, String keyword, int start, int size) {
|
||||
Set<String> keys = stringRedisTemplate.keys(prefix + "*" + keyword + "*");
|
||||
List<String> list = new ArrayList<String>(keys);
|
||||
return SaTokenInsideUtil.searchList(list, start, size);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,5 +1,8 @@
|
||||
package cn.dev33.satoken.dao;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -11,6 +14,7 @@ import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import cn.dev33.satoken.session.SaSession;
|
||||
import cn.dev33.satoken.util.SaTokenInsideUtil;
|
||||
|
||||
/**
|
||||
* sa-token持久层的实现类, 基于redis
|
||||
@@ -162,5 +166,18 @@ public class SaTokenDaoRedis implements SaTokenDao {
|
||||
public void updateSessionTimeout(String sessionId, long timeout) {
|
||||
sessionRedisTemplate.expire(sessionId, timeout, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 搜索数据
|
||||
*/
|
||||
@Override
|
||||
public List<String> searchData(String prefix, String keyword, int start, int size) {
|
||||
Set<String> keys = stringRedisTemplate.keys(prefix + "*" + keyword + "*");
|
||||
List<String> list = new ArrayList<String>(keys);
|
||||
return SaTokenInsideUtil.searchList(list, start, size);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -9,6 +9,8 @@ import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
|
||||
import com.pj.util.AjaxJson;
|
||||
|
||||
import cn.dev33.satoken.exception.NotLoginException;
|
||||
import cn.dev33.satoken.exception.NotPermissionException;
|
||||
import cn.dev33.satoken.exception.NotRoleException;
|
||||
|
@@ -0,0 +1,62 @@
|
||||
package com.pj.test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.pj.util.AjaxJson;
|
||||
import com.pj.util.Ttime;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
|
||||
/**
|
||||
* 压力测试
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/s-test/")
|
||||
public class StressTestController {
|
||||
|
||||
|
||||
// 测试 浏览器访问: http://localhost:8081/s-test/login
|
||||
// 测试前,请先将 is-read-cookie 配置为 false
|
||||
@RequestMapping("login")
|
||||
public AjaxJson login() {
|
||||
// StpUtil.getTokenSession().logout();
|
||||
// StpUtil.logoutByLoginId(10001);
|
||||
// 循环10次 取平均时间
|
||||
List<Double> list = new ArrayList<>();
|
||||
for (int i = 10; i <= 1; i++) {
|
||||
System.out.println("\n---------------------第" + i + "轮---------------------");
|
||||
Ttime t = new Ttime().start();
|
||||
// 每次登录的次数
|
||||
for (int j = 1; j <= 10000; j++) {
|
||||
StpUtil.setLoginId("1000" + j, "PC-" + j);
|
||||
if(j % 1000 == 0) {
|
||||
System.out.println("已登录:" + j);
|
||||
}
|
||||
}
|
||||
t.end();
|
||||
list.add((t.returnMs() + 0.0) / 1000);
|
||||
System.out.println("第" + i + "轮" + "用时:" + t.toString());
|
||||
}
|
||||
// System.out.println(((SaTokenDaoDefaultImpl)SaTokenManager.getSaTokenDao()).dataMap.size());
|
||||
|
||||
System.out.println("\n---------------------测试结果---------------------");
|
||||
System.out.println(list.size() + "次测试: " + list);
|
||||
double ss = 0;
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
ss += list.get(i);
|
||||
}
|
||||
System.out.println("平均用时: " + ss / list.size());
|
||||
return AjaxJson.getSuccess();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@@ -1,6 +1,7 @@
|
||||
package com.pj.test;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
@@ -8,6 +9,8 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.pj.util.AjaxJson;
|
||||
import com.pj.util.Ttime;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
@@ -191,17 +194,7 @@ public class TestController {
|
||||
// 返回
|
||||
return AjaxJson.getSuccess();
|
||||
}
|
||||
|
||||
// 测试 浏览器访问: http://localhost:8081/test/test
|
||||
@RequestMapping("test")
|
||||
public AjaxJson test() {
|
||||
// StpUtil.getTokenSession().logout();
|
||||
StpUtil.logoutByLoginId(10001);
|
||||
return AjaxJson.getSuccess();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 测试登录接口, 按照设备登录, 浏览器访问: http://localhost:8081/test/login2
|
||||
@RequestMapping("login2")
|
||||
public AjaxJson login2(@RequestParam(defaultValue="10001") String id, @RequestParam(defaultValue="PC") String device) {
|
||||
@@ -209,4 +202,30 @@ public class TestController {
|
||||
return AjaxJson.getSuccess();
|
||||
}
|
||||
|
||||
|
||||
// 测试 浏览器访问: http://localhost:8081/test/searchSession
|
||||
// 测试前,请先将 is-read-cookie 配置为 false
|
||||
@RequestMapping("searchSession")
|
||||
public AjaxJson searchSession() {
|
||||
System.out.println("--------------");
|
||||
Ttime t = new Ttime().start();
|
||||
List<String> tokenValue = StpUtil.searchTokenValue("", 0, 10);
|
||||
for (String v : tokenValue) {
|
||||
// SaSession session = StpUtil.getSessionBySessionId(sid);
|
||||
System.out.println(v);
|
||||
}
|
||||
System.out.println("用时:" + t.end().toString());
|
||||
return AjaxJson.getSuccess();
|
||||
}
|
||||
|
||||
|
||||
// 测试 浏览器访问: http://localhost:8081/test/test
|
||||
@RequestMapping("test")
|
||||
public AjaxJson test() {
|
||||
StpUtil.getTokenSession().logout();
|
||||
StpUtil.logoutByLoginId(10001);
|
||||
return AjaxJson.getSuccess();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
package com.pj.test;
|
||||
package com.pj.util;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
@@ -0,0 +1,63 @@
|
||||
package com.pj.util;
|
||||
|
||||
|
||||
/**
|
||||
* 用于测试用时
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class Ttime {
|
||||
|
||||
private long start=0; //开始时间
|
||||
private long end=0; //结束时间
|
||||
|
||||
public static Ttime t = new Ttime(); //static快捷使用
|
||||
|
||||
/**
|
||||
* 开始计时
|
||||
* @return
|
||||
*/
|
||||
public Ttime start() {
|
||||
start=System.currentTimeMillis();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 结束计时
|
||||
*/
|
||||
public Ttime end() {
|
||||
end=System.currentTimeMillis();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 返回所用毫秒数
|
||||
*/
|
||||
public long returnMs() {
|
||||
return end-start;
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化输出结果
|
||||
*/
|
||||
public void outTime() {
|
||||
System.out.println(this.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束并格式化输出结果
|
||||
*/
|
||||
public void endOutTime() {
|
||||
this.end().outTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return (returnMs() + 0.0) / 1000 + "s"; // 格式化为:0.01s
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@@ -18,11 +18,14 @@ spring:
|
||||
# token风格
|
||||
token-style: uuid
|
||||
|
||||
# 是否从cookie里读取token
|
||||
# is-read-cookie: false
|
||||
|
||||
|
||||
# redis配置
|
||||
redis:
|
||||
# Redis数据库索引(默认为0)
|
||||
database: 1
|
||||
database: 0
|
||||
# Redis服务器地址
|
||||
host: 127.0.0.1
|
||||
# Redis服务器连接端口
|
||||
@@ -30,7 +33,7 @@ spring:
|
||||
# Redis服务器连接密码(默认为空)
|
||||
password:
|
||||
# 连接超时时间(毫秒)
|
||||
timeout: 1000ms
|
||||
timeout: 10000ms
|
||||
lettuce:
|
||||
pool:
|
||||
# 连接池最大连接数
|
||||
|
@@ -18,6 +18,7 @@
|
||||
- [注解式鉴权](/use/at-check)
|
||||
- [花式token](/use/token-style)
|
||||
- [框架配置](/use/config)
|
||||
- [会话治理](/use/search-session)
|
||||
|
||||
- **其它**
|
||||
- [常见问题](/more/common-questions)
|
||||
|
48
sa-token-doc/doc/use/search-session.md
Normal file
48
sa-token-doc/doc/use/search-session.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# 会话治理
|
||||
|
||||
尽管框架将大部分操作提供了简易的封装,但在一些特殊场景下,我们仍需要绕过框架,直达数据底层进行一些操作 <br>
|
||||
sa-token提供以下API助你直接操作会话列表
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 具体API
|
||||
|
||||
#### 查询所有token
|
||||
``` java
|
||||
StpUtil.searchTokenValue(String keyword, int start, int size);
|
||||
```
|
||||
|
||||
#### 查询所有账号Session会话
|
||||
``` java
|
||||
StpUtil.searchSessionId(String keyword, int start, int size);
|
||||
```
|
||||
|
||||
|
||||
#### 查询所有令牌Session会话
|
||||
``` java
|
||||
StpUtil.searchTokenSessionId(String keyword, int start, int size);
|
||||
```
|
||||
|
||||
|
||||
#### 参数详解:
|
||||
- `keyword`: 查询关键字,只有包括这个字符串的token值才会被查询出来
|
||||
- `start`: 数据开始处索引, 值为-1时代表一次性取出所有数据
|
||||
- `size`: 要获取的数据条数
|
||||
|
||||
使用示例:
|
||||
``` java
|
||||
StpUtil.searchTokenValue("1000", 0, 10); // 查询value包括1000的所有token,结果集从第0条开始,返回10条
|
||||
```
|
||||
|
||||
|
||||
<br/>
|
||||
|
||||
#### 注意事项:
|
||||
由于会话查询底层采用了遍历方式获取数据,当数据量过大时此操作将会比较耗时,有多耗时呢?这里提供一份参考数据:
|
||||
- 单机模式下:百万会话取出10条token平均耗时 `0.255s`
|
||||
- Redis模式下:百万会话取出10条token平均耗时 `3.322s`
|
||||
|
||||
请根据业务实际水平合理调用API
|
||||
|
||||
|
Reference in New Issue
Block a user