refactor: 重构 SaTokenDao 相关代码,减少重复代码

This commit is contained in:
click33 2025-02-22 04:36:02 +08:00
parent 7c3febda60
commit 362b08b9b8
25 changed files with 533 additions and 297 deletions

View File

@ -15,7 +15,6 @@
*/
package cn.dev33.satoken.dao;
import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.session.SaSession;
import java.util.List;
@ -95,10 +94,7 @@ public interface SaTokenDao {
* @param key 键名称
* @return object
*/
default Object getObject(String key) {
String jsonString = get(key);
return SaManager.getSaJsonTemplate().jsonToObject(jsonString);
}
Object getObject(String key);
/**
* 写入 Object并设定存活时间 单位:
@ -107,46 +103,34 @@ public interface SaTokenDao {
* @param object
* @param timeout 存活时间值大于0时限时存储=-1时永久存储=0或小于-2时不存储
*/
default void setObject(String key, Object object, long timeout) {
String jsonString = SaManager.getSaJsonTemplate().objectToJson(object);
set(key, jsonString, timeout);
}
void setObject(String key, Object object, long timeout);
/**
* 更新 Object 过期时间不变
* @param key 键名称
* @param object
*/
default void updateObject(String key, Object object) {
String jsonString = SaManager.getSaJsonTemplate().objectToJson(object);
update(key, jsonString);
}
void updateObject(String key, Object object);
/**
* 删除 Object
* @param key 键名称
*/
default void deleteObject(String key) {
delete(key);
}
void deleteObject(String key);
/**
* 获取 Object 的剩余存活时间 单位:
* @param key 指定 key
* @return 这个 key 的剩余存活时间
*/
default long getObjectTimeout(String key) {
return getTimeout(key);
}
long getObjectTimeout(String key);
/**
* 修改 Object 的剩余存活时间单位:
* @param key 指定 key
* @param timeout 剩余存活时间
*/
default void updateObjectTimeout(String key, long timeout) {
updateTimeout(key, timeout);
}
void updateObjectTimeout(String key, long timeout);
// --------------------- SaSession 读写 默认复用 Object 读写方法 ---------------------
@ -156,52 +140,40 @@ public interface SaTokenDao {
* @param sessionId sessionId
* @return SaSession
*/
default SaSession getSession(String sessionId) {
return (SaSession)getObject(sessionId);
}
SaSession getSession(String sessionId);
/**
* 写入 SaSession并设定存活时间单位:
* @param session 要保存的 SaSession 对象
* @param timeout 过期时间单位:
*/
default void setSession(SaSession session, long timeout) {
setObject(session.getId(), session, timeout);
}
void setSession(SaSession session, long timeout);
/**
* 更新 SaSession
* @param session 要更新的 SaSession 对象
*/
default void updateSession(SaSession session) {
updateObject(session.getId(), session);
}
void updateSession(SaSession session);
/**
* 删除 SaSession
* @param sessionId sessionId
*/
default void deleteSession(String sessionId) {
deleteObject(sessionId);
}
void deleteSession(String sessionId);
/**
* 获取 SaSession 剩余存活时间单位:
* @param sessionId 指定 SaSession
* @return 这个 SaSession 的剩余存活时间
*/
default long getSessionTimeout(String sessionId) {
return getObjectTimeout(sessionId);
}
long getSessionTimeout(String sessionId);
/**
* 修改 SaSession 剩余存活时间单位:
* @param sessionId 指定 SaSession
* @param timeout 剩余存活时间
*/
default void updateSessionTimeout(String sessionId, long timeout) {
updateObjectTimeout(sessionId, timeout);
}
void updateSessionTimeout(String sessionId, long timeout);
// --------------------- 会话管理 ---------------------

View File

@ -16,250 +16,71 @@
package cn.dev33.satoken.dao;
import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.dao.auto.SaTokenDaoByStringFollowObject;
import cn.dev33.satoken.dao.timedcache.SaTimedCache;
import cn.dev33.satoken.util.SaFoxUtil;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Sa-Token 持久层接口默认实现类基于内存 Map系统重启后数据丢失
* Sa-Token 持久层接口默认实现类基于 SaTimedCache 内存 Map系统重启后数据丢失
*
* @author click33
* @since 1.10.0
*/
public class SaTokenDaoDefaultImpl implements SaTokenDao {
/**
* 存储数据的集合
*/
public Map<String, Object> dataMap = new ConcurrentHashMap<>();
/**
* 存储数据过期时间的集合单位: 毫秒, 记录所有 key 的到期时间 注意存储的是到期时间不是剩余存活时间
*/
public Map<String, Long> expireMap = new ConcurrentHashMap<>();
// ------------------------ String 读写操作
@Override
public String get(String key) {
clearKeyByTimeout(key);
return (String)dataMap.get(key);
}
@Override
public void set(String key, String value, long timeout) {
if(timeout == 0 || timeout <= SaTokenDao.NOT_VALUE_EXPIRE) {
return;
}
dataMap.put(key, value);
expireMap.put(key, (timeout == SaTokenDao.NEVER_EXPIRE) ? (SaTokenDao.NEVER_EXPIRE) : (System.currentTimeMillis() + timeout * 1000));
}
@Override
public void update(String key, String value) {
if(getKeyTimeout(key) == SaTokenDao.NOT_VALUE_EXPIRE) {
return;
}
dataMap.put(key, value);
}
@Override
public void delete(String key) {
dataMap.remove(key);
expireMap.remove(key);
}
@Override
public long getTimeout(String key) {
return getKeyTimeout(key);
}
@Override
public void updateTimeout(String key, long timeout) {
expireMap.put(key, (timeout == SaTokenDao.NEVER_EXPIRE) ? (SaTokenDao.NEVER_EXPIRE) : (System.currentTimeMillis() + timeout * 1000));
}
public class SaTokenDaoDefaultImpl implements SaTokenDaoByStringFollowObject {
public SaTimedCache timedCache = new SaTimedCache();
// ------------------------ Object 读写操作
@Override
public Object getObject(String key) {
clearKeyByTimeout(key);
return dataMap.get(key);
return timedCache.getObject(key);
}
@Override
public void setObject(String key, Object object, long timeout) {
if(timeout == 0 || timeout <= SaTokenDao.NOT_VALUE_EXPIRE) {
return;
}
dataMap.put(key, object);
expireMap.put(key, (timeout == SaTokenDao.NEVER_EXPIRE) ? (SaTokenDao.NEVER_EXPIRE) : (System.currentTimeMillis() + timeout * 1000));
timedCache.setObject(key, object, timeout);
}
@Override
public void updateObject(String key, Object object) {
if(getKeyTimeout(key) == SaTokenDao.NOT_VALUE_EXPIRE) {
return;
}
dataMap.put(key, object);
timedCache.updateObject(key, object);
}
@Override
public void deleteObject(String key) {
dataMap.remove(key);
expireMap.remove(key);
timedCache.deleteObject(key);
}
@Override
public long getObjectTimeout(String key) {
return getKeyTimeout(key);
return timedCache.getObjectTimeout(key);
}
@Override
public void updateObjectTimeout(String key, long timeout) {
expireMap.put(key, (timeout == SaTokenDao.NEVER_EXPIRE) ? (SaTokenDao.NEVER_EXPIRE) : (System.currentTimeMillis() + timeout * 1000));
timedCache.updateObjectTimeout(key, timeout);
}
// ------------------------ Session 读写操作
// 使用接口默认实现
// --------- 会话管理
@Override
public List<String> searchData(String prefix, String keyword, int start, int size, boolean sortType) {
return SaFoxUtil.searchList(expireMap.keySet(), prefix, keyword, start, size, sortType);
return SaFoxUtil.searchList(timedCache.expireMap.keySet(), prefix, keyword, start, size, sortType);
}
// ------------------------ 以下是一个定时缓存的简单实现采用惰性检查 + 异步循环扫描
// --------- 过期时间相关操作
/**
* 如果指定的 key 已经过期则立即清除它
* @param key 指定 key
*/
void clearKeyByTimeout(String key) {
Long expirationTime = expireMap.get(key);
// 清除条件
// 1数据存在
// 2不是 [ 永不过期 ]
// 3已经超过过期时间
if(expirationTime != null && expirationTime != SaTokenDao.NEVER_EXPIRE && expirationTime < System.currentTimeMillis()) {
dataMap.remove(key);
expireMap.remove(key);
}
}
/**
* 获取指定 key 的剩余存活时间 单位
* @param key 指定 key
* @return 这个 key 的剩余存活时间
*/
long getKeyTimeout(String key) {
// 由于数据过期检测属于惰性扫描很可能此时这个 key 已经是过期状态了所以这里需要先检查一下
clearKeyByTimeout(key);
// 获取这个 key 的过期时间
Long expire = expireMap.get(key);
// 如果 expire 数据不存在说明框架没有存储这个 key此时返回 NOT_VALUE_EXPIRE
if(expire == null) {
return SaTokenDao.NOT_VALUE_EXPIRE;
}
// 如果 expire 被标注为永不过期则返回 NEVER_EXPIRE
if(expire == SaTokenDao.NEVER_EXPIRE) {
return SaTokenDao.NEVER_EXPIRE;
}
// ---- 代码至此说明这个 key 是有过期时间的且未过期那么
// 计算剩余时间并返回 过期时间戳 - 当前时间戳 / 1000 转秒
long timeout = (expire - System.currentTimeMillis()) / 1000;
// 小于零时视为不存在
if(timeout < 0) {
dataMap.remove(key);
expireMap.remove(key);
return SaTokenDao.NOT_VALUE_EXPIRE;
}
return timeout;
}
// --------- 定时清理过期数据
/**
* 执行数据清理的线程引用
*/
public Thread refreshThread;
/**
* 是否继续执行数据清理的线程标记
*/
public volatile boolean refreshFlag;
/**
* 清理所有已经过期的 key
*/
public void refreshDataMap() {
for (String s : expireMap.keySet()) {
clearKeyByTimeout(s);
}
}
/**
* 初始化定时任务定时清理过期数据
*/
public void initRefreshThread() {
// 如果开发者配置了 <=0 的值则不启动定时清理
if(SaManager.getConfig().getDataRefreshPeriod() <= 0) {
return;
}
// 启动定时刷新
this.refreshFlag = true;
this.refreshThread = new Thread(() -> {
for (;;) {
try {
try {
// 如果已经被标记为结束
if( ! refreshFlag) {
return;
}
// 执行清理
refreshDataMap();
} catch (Exception e) {
e.printStackTrace();
}
// 休眠N秒
int dataRefreshPeriod = SaManager.getConfig().getDataRefreshPeriod();
if(dataRefreshPeriod <= 0) {
dataRefreshPeriod = 1;
}
Thread.sleep(dataRefreshPeriod * 1000L);
} catch (Exception e) {
e.printStackTrace();
}
}
});
this.refreshThread.start();
}
// --------- 组件生命周期
/**
* 组件被安装时开始刷新数据线程
*/
@Override
public void init() {
initRefreshThread();
timedCache.initRefreshThread();
}
/**
@ -267,6 +88,6 @@ public class SaTokenDaoDefaultImpl implements SaTokenDao {
*/
@Override
public void destroy() {
this.refreshFlag = false;
timedCache.endRefreshThread();
}
}

View File

@ -0,0 +1,95 @@
/*
* Copyright 2020-2099 sa-token.cc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.dev33.satoken.dao.auto;
import cn.dev33.satoken.SaManager;
/**
* SaTokenDao 次级实现 JSON 序列化方式实现 Object 读写相关操作
*
* @author click33
* @since 1.41.0
*/
public interface SaTokenDaoByObjectFollowStringUseJsonSerializer extends SaTokenDaoBySessionFollowObject {
// --------------------- Object 读写 ---------------------
/**
* 获取 Object如无返空
*
* @param key 键名称
* @return object
*/
@Override
default Object getObject(String key) {
String jsonString = get(key);
return SaManager.getSaJsonTemplate().jsonToObject(jsonString);
}
/**
* 写入 Object并设定存活时间 单位:
*
* @param key 键名称
* @param object
* @param timeout 存活时间值大于0时限时存储=-1时永久存储=0或小于-2时不存储
*/
@Override
default void setObject(String key, Object object, long timeout) {
String jsonString = SaManager.getSaJsonTemplate().objectToJson(object);
set(key, jsonString, timeout);
}
/**
* 更新 Object 过期时间不变
* @param key 键名称
* @param object
*/
@Override
default void updateObject(String key, Object object) {
String jsonString = SaManager.getSaJsonTemplate().objectToJson(object);
update(key, jsonString);
}
/**
* 删除 Object
* @param key 键名称
*/
@Override
default void deleteObject(String key) {
delete(key);
}
/**
* 获取 Object 的剩余存活时间 单位:
* @param key 指定 key
* @return 这个 key 的剩余存活时间
*/
@Override
default long getObjectTimeout(String key) {
return getTimeout(key);
}
/**
* 修改 Object 的剩余存活时间单位:
* @param key 指定 key
* @param timeout 剩余存活时间
*/
@Override
default void updateObjectTimeout(String key, long timeout) {
updateTimeout(key, timeout);
}
}

View File

@ -0,0 +1,83 @@
/*
* Copyright 2020-2099 sa-token.cc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.dev33.satoken.dao.auto;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.session.SaSession;
/**
* SaTokenDao 次级实现SaSession 读写跟随 Object 读写
*
* @author click33
* @since 1.41.0
*/
public interface SaTokenDaoBySessionFollowObject extends SaTokenDao {
// --------------------- SaSession 读写 默认复用 Object 读写方法 ---------------------
/**
* 获取 SaSession如无返空
* @param sessionId sessionId
* @return SaSession
*/
default SaSession getSession(String sessionId) {
return (SaSession)getObject(sessionId);
}
/**
* 写入 SaSession并设定存活时间单位:
* @param session 要保存的 SaSession 对象
* @param timeout 过期时间单位:
*/
default void setSession(SaSession session, long timeout) {
setObject(session.getId(), session, timeout);
}
/**
* 更新 SaSession
* @param session 要更新的 SaSession 对象
*/
default void updateSession(SaSession session) {
updateObject(session.getId(), session);
}
/**
* 删除 SaSession
* @param sessionId sessionId
*/
default void deleteSession(String sessionId) {
deleteObject(sessionId);
}
/**
* 获取 SaSession 剩余存活时间单位:
* @param sessionId 指定 SaSession
* @return 这个 SaSession 的剩余存活时间
*/
default long getSessionTimeout(String sessionId) {
return getObjectTimeout(sessionId);
}
/**
* 修改 SaSession 剩余存活时间单位:
* @param sessionId 指定 SaSession
* @param timeout 剩余存活时间
*/
default void updateSessionTimeout(String sessionId, long timeout) {
updateObjectTimeout(sessionId, timeout);
}
}

View File

@ -0,0 +1,58 @@
/*
* Copyright 2020-2099 sa-token.cc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.dev33.satoken.dao.auto;
/**
* SaTokenDao 次级实现String 读写跟随 Object 读写
*
* @author click33
* @since 1.41.0
*/
public interface SaTokenDaoByStringFollowObject extends SaTokenDaoBySessionFollowObject {
// --------------------- String 读写 ---------------------
@Override
default String get(String key) {
return (String) getObject(key);
}
@Override
default void set(String key, String value, long timeout) {
setObject(key, value, timeout);
}
@Override
default void update(String key, String value) {
updateObject(key, value);
}
@Override
default void delete(String key) {
deleteObject(key);
}
@Override
default long getTimeout(String key) {
return getObjectTimeout(key);
}
@Override
default void updateTimeout(String key, long timeout) {
updateObjectTimeout(key, timeout);
}
}

View File

@ -0,0 +1,201 @@
/*
* Copyright 2020-2099 sa-token.cc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.dev33.satoken.dao.timedcache;
import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.dao.SaTokenDao;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 一个定时缓存的简单实现采用惰性检查 + 异步循环扫描
*
* @author click33
* @since 1.41.0
*/
public class SaTimedCache {
/**
* 存储数据的集合
*/
public Map<String, Object> dataMap = new ConcurrentHashMap<>();
/**
* 存储数据过期时间的集合单位: 毫秒, 记录所有 key 的到期时间 注意存储的是到期时间不是剩余存活时间
*/
public Map<String, Long> expireMap = new ConcurrentHashMap<>();
// ------------------------ 基础 API 读写操作
public Object getObject(String key) {
clearKeyByTimeout(key);
return dataMap.get(key);
}
public void setObject(String key, Object object, long timeout) {
if(timeout == 0 || timeout <= SaTokenDao.NOT_VALUE_EXPIRE) {
return;
}
dataMap.put(key, object);
expireMap.put(key, (timeout == SaTokenDao.NEVER_EXPIRE) ? (SaTokenDao.NEVER_EXPIRE) : (System.currentTimeMillis() + timeout * 1000));
}
public void updateObject(String key, Object object) {
if(getKeyTimeout(key) == SaTokenDao.NOT_VALUE_EXPIRE) {
return;
}
dataMap.put(key, object);
}
public void deleteObject(String key) {
dataMap.remove(key);
expireMap.remove(key);
}
public long getObjectTimeout(String key) {
return getKeyTimeout(key);
}
public void updateObjectTimeout(String key, long timeout) {
expireMap.put(key, (timeout == SaTokenDao.NEVER_EXPIRE) ? (SaTokenDao.NEVER_EXPIRE) : (System.currentTimeMillis() + timeout * 1000));
}
// --------- 过期时间相关操作
/**
* 如果指定的 key 已经过期则立即清除它
* @param key 指定 key
*/
void clearKeyByTimeout(String key) {
Long expirationTime = expireMap.get(key);
// 清除条件
// 1数据存在
// 2不是 [ 永不过期 ]
// 3已经超过过期时间
if(expirationTime != null && expirationTime != SaTokenDao.NEVER_EXPIRE && expirationTime < System.currentTimeMillis()) {
dataMap.remove(key);
expireMap.remove(key);
}
}
/**
* 获取指定 key 的剩余存活时间 单位
* @param key 指定 key
* @return 这个 key 的剩余存活时间
*/
long getKeyTimeout(String key) {
// 由于数据过期检测属于惰性扫描很可能此时这个 key 已经是过期状态了所以这里需要先检查一下
clearKeyByTimeout(key);
// 获取这个 key 的过期时间
Long expire = expireMap.get(key);
// 如果 expire 数据不存在说明框架没有存储这个 key此时返回 NOT_VALUE_EXPIRE
if(expire == null) {
return SaTokenDao.NOT_VALUE_EXPIRE;
}
// 如果 expire 被标注为永不过期则返回 NEVER_EXPIRE
if(expire == SaTokenDao.NEVER_EXPIRE) {
return SaTokenDao.NEVER_EXPIRE;
}
// ---- 代码至此说明这个 key 是有过期时间的且未过期那么
// 计算剩余时间并返回 过期时间戳 - 当前时间戳 / 1000 转秒
long timeout = (expire - System.currentTimeMillis()) / 1000;
// 小于零时视为不存在
if(timeout < 0) {
dataMap.remove(key);
expireMap.remove(key);
return SaTokenDao.NOT_VALUE_EXPIRE;
}
return timeout;
}
// --------- 定时清理过期数据
/**
* 执行数据清理的线程引用
*/
public Thread refreshThread;
/**
* 是否继续执行数据清理的线程标记
*/
public volatile boolean refreshFlag;
/**
* 清理所有已经过期的 key
*/
public void refreshDataMap() {
for (String s : expireMap.keySet()) {
clearKeyByTimeout(s);
}
}
/**
* 初始化定时任务定时清理过期数据
*/
public void initRefreshThread() {
// 如果开发者配置了 <=0 的值则不启动定时清理
if(SaManager.getConfig().getDataRefreshPeriod() <= 0) {
return;
}
// 启动定时刷新
this.refreshFlag = true;
this.refreshThread = new Thread(() -> {
for (;;) {
try {
try {
// 如果已经被标记为结束
if( ! refreshFlag) {
return;
}
// 执行清理
refreshDataMap();
} catch (Exception e) {
e.printStackTrace();
}
// 休眠N秒
int dataRefreshPeriod = SaManager.getConfig().getDataRefreshPeriod();
if(dataRefreshPeriod <= 0) {
dataRefreshPeriod = 1;
}
Thread.sleep(dataRefreshPeriod * 1000L);
} catch (Exception e) {
e.printStackTrace();
}
}
});
this.refreshThread.start();
}
/**
* 结束定时任务
*/
public void endRefreshThread() {
this.refreshFlag = false;
}
}

View File

@ -37,6 +37,7 @@
<fastjson.version>1.2.83</fastjson.version>
<fastjson2.version>2.0.15</fastjson2.version>
<redisson.version>3.19.0</redisson.version>
<hutool-cache.version>5.8.36</hutool-cache.version>
</properties>
<dependencyManagement>
@ -257,6 +258,13 @@
<version>${jjwt.version}</version>
</dependency>
<!-- Hutool Cache -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-cache</artifactId>
<version>${hutool-cache.version}</version>
</dependency>
<!-- sa-token 自身依赖 -->
<dependency>
<groupId>cn.dev33</groupId>

View File

@ -24,12 +24,12 @@
<module>sa-token-redis-jackson</module>
<module>sa-token-fastjson</module>
<module>sa-token-fastjson2</module>
<module>sa-token-hutool-timed-cache</module>
<module>sa-token-redisson-jackson</module>
<module>sa-token-redisson-jackson2</module>
<module>sa-token-redisx</module>
<module>sa-token-alone-redis</module>
<module>sa-token-hutool-timed-cache</module>
<module>sa-token-dialect-thymeleaf</module>
<module>sa-token-freemarker</module>
<module>sa-token-sso</module>

View File

@ -26,7 +26,7 @@ import cn.dev33.satoken.strategy.SaStrategy;
* @author click33
* @since 1.41.0
*/
public class SaTokenPluginFastjson implements SaTokenPlugin {
public class SaTokenPluginForFastjson implements SaTokenPlugin {
@Override
public void setup() {

View File

@ -1 +1 @@
cn.dev33.satoken.plugin.SaTokenPluginFastjson
cn.dev33.satoken.plugin.SaTokenPluginForFastjson

View File

@ -26,7 +26,7 @@ import cn.dev33.satoken.strategy.SaStrategy;
* @author click33
* @since 1.41.0
*/
public class SaTokenPluginFastjson2 implements SaTokenPlugin {
public class SaTokenPluginForFastjson2 implements SaTokenPlugin {
@Override
public void setup() {

View File

@ -1 +1 @@
cn.dev33.satoken.plugin.SaTokenPluginFastjson2
cn.dev33.satoken.plugin.SaTokenPluginForFastjson2

View File

@ -17,19 +17,14 @@
<description>sa-token integrate hutool-TimedCache</description>
<dependencies>
<!-- sa-token-spring-boot-starter -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-core</artifactId>
</dependency>
<!-- Hutool Cache -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-cache</artifactId>
<version>5.8.27</version>
</dependency>
</dependencies>
</project>

View File

@ -17,6 +17,7 @@ package cn.dev33.satoken.dao;
import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.dao.auto.SaTokenDaoByStringFollowObject;
import cn.dev33.satoken.util.SaFoxUtil;
import cn.hutool.cache.CacheUtil;
import cn.hutool.cache.impl.CacheObj;
@ -31,7 +32,7 @@ import java.util.List;
* @author click33
* @since 1.38.0
*/
public class SaTokenDaoForHutoolTimedCache implements SaTokenDao {
public class SaTokenDaoForHutoolTimedCache implements SaTokenDaoByStringFollowObject {
//
/**
@ -41,39 +42,6 @@ public class SaTokenDaoForHutoolTimedCache implements SaTokenDao {
public TimedCache<String, Object> timedCache = CacheUtil.newTimedCache(1000);
// ------------------------ String 读写操作
@Override
public String get(String key) {
return (String) getObject(key);
}
@Override
public void set(String key, String value, long timeout) {
setObject(key, value, timeout);
}
@Override
public void update(String key, String value) {
updateObject(key, value);
}
@Override
public void delete(String key) {
deleteObject(key);
}
@Override
public long getTimeout(String key) {
return getObjectTimeout(key);
}
@Override
public void updateTimeout(String key, long timeout) {
updateObjectTimeout(key, timeout);
}
// ------------------------ Object 读写操作
@Override

View File

@ -0,0 +1,36 @@
/*
* Copyright 2020-2099 sa-token.cc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.dev33.satoken.plugin;
import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.dao.SaTokenDaoForHutoolTimedCache;
/**
* SaToken 插件安装DAO 扩展 - Hutool-TimedCache
*
* @author click33
* @since 1.41.0
*/
public class SaTokenPluginForHutoolCache implements SaTokenPlugin {
@Override
public void setup() {
SaManager.setSaTokenDao(new SaTokenDaoForHutoolTimedCache());
}
}

View File

@ -0,0 +1 @@
cn.dev33.satoken.plugin.SaTokenPluginForHutoolCache

View File

@ -1 +0,0 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.dev33.satoken.dao.SaTokenDaoForHutoolTimedCache

View File

@ -16,6 +16,7 @@
package cn.dev33.satoken.dao.impl;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.dao.auto.SaTokenDaoByObjectFollowStringUseJsonSerializer;
import cn.dev33.satoken.util.SaFoxUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisConnectionFactory;
@ -34,7 +35,7 @@ import java.util.concurrent.TimeUnit;
* @since 1.34.0
*/
@Component
public class SaTokenDaoForRedisTemplate implements SaTokenDao {
public class SaTokenDaoForRedisTemplate implements SaTokenDaoByObjectFollowStringUseJsonSerializer {
public StringRedisTemplate stringRedisTemplate;

View File

@ -15,12 +15,11 @@
*/
package cn.dev33.satoken.core.json;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import cn.dev33.satoken.exception.NotImplException;
import cn.dev33.satoken.json.SaJsonTemplateDefaultImpl;
import cn.dev33.satoken.util.SoMap;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
/**
* json默认实现类测试
@ -35,11 +34,11 @@ public class SaJsonTemplateDefaultImplTest {
SaJsonTemplateDefaultImpl saJsonTemplate = new SaJsonTemplateDefaultImpl();
// 组件未实现
Assertions.assertThrows(NotImplException.class, () -> {
saJsonTemplate.parseJsonToMap("{}");
saJsonTemplate.jsonToMap("{}");
});
// 组件未实现
Assertions.assertThrows(NotImplException.class, () -> {
saJsonTemplate.toJsonString(SoMap.getSoMap("name", "zhangsan"));
saJsonTemplate.objectToJson(SoMap.getSoMap("name", "zhangsan"));
});
}

View File

@ -163,7 +163,7 @@ public class SaAnnotationControllerTest {
// Map
String content = mvcResult.getResponse().getContentAsString();
Map<String, Object> map = SaManager.getSaJsonTemplate().parseJsonToMap(content);
Map<String, Object> map = SaManager.getSaJsonTemplate().jsonToMap(content);
// SaResult 对象
return new SaResult().setMap(map);

View File

@ -96,7 +96,7 @@ public class MoreControllerTest {
// Map
String content = mvcResult.getResponse().getContentAsString();
Map<String, Object> map = SaManager.getSaJsonTemplate().parseJsonToMap(content);
Map<String, Object> map = SaManager.getSaJsonTemplate().jsonToMap(content);
// SaResult 对象
SaResult res = new SaResult().setMap(map);
Assertions.assertEquals(res.getCode(), 903);
@ -117,7 +117,7 @@ public class MoreControllerTest {
// Map
String content2 = mvcResult2.getResponse().getContentAsString();
Map<String, Object> map2 = SaManager.getSaJsonTemplate().parseJsonToMap(content2);
Map<String, Object> map2 = SaManager.getSaJsonTemplate().jsonToMap(content2);
// SaResult 对象
SaResult res2 = new SaResult().setMap(map2);
Assertions.assertEquals(res2.getCode(), 200);
@ -139,7 +139,7 @@ public class MoreControllerTest {
// Map
String content = mvcResult.getResponse().getContentAsString();
Map<String, Object> map = SaManager.getSaJsonTemplate().parseJsonToMap(content);
Map<String, Object> map = SaManager.getSaJsonTemplate().jsonToMap(content);
// SaResult 对象
return new SaResult().setMap(map);

View File

@ -202,7 +202,7 @@ public class RouterControllerTest {
// Map
String content = mvcResult.getResponse().getContentAsString();
Map<String, Object> map = SaManager.getSaJsonTemplate().parseJsonToMap(content);
Map<String, Object> map = SaManager.getSaJsonTemplate().jsonToMap(content);
// SaResult 对象
SaResult res = new SaResult().setMap(map);
@ -261,7 +261,7 @@ public class RouterControllerTest {
// Map
String content = mvcResult.getResponse().getContentAsString();
Map<String, Object> map = SaManager.getSaJsonTemplate().parseJsonToMap(content);
Map<String, Object> map = SaManager.getSaJsonTemplate().jsonToMap(content);
// SaResult 对象
return new SaResult().setMap(map);

View File

@ -132,7 +132,7 @@ public class SaSameTokenControllerTest {
// Map
String content = mvcResult.getResponse().getContentAsString();
Map<String, Object> map = SaManager.getSaJsonTemplate().parseJsonToMap(content);
Map<String, Object> map = SaManager.getSaJsonTemplate().jsonToMap(content);
// SaResult 对象
return new SaResult().setMap(map);

View File

@ -743,18 +743,18 @@ public class BasicsTest {
// map json
SoMap map = SoMap.getSoMap("name", "zhangsan");
String jsonString = saJsonTemplate.toJsonString(map);
String jsonString = saJsonTemplate.objectToJson(map);
Assertions.assertEquals(jsonString, "{\"name\":\"zhangsan\"}");
// 抛异常
Assertions.assertThrows(SaJsonConvertException.class, () -> saJsonTemplate.toJsonString(new Object()));
Assertions.assertThrows(SaJsonConvertException.class, () -> saJsonTemplate.objectToJson(new Object()));
// json map
Map<String, Object> map2 = saJsonTemplate.parseJsonToMap("{\"name\":\"zhangsan\"}");
Map<String, Object> map2 = saJsonTemplate.jsonToMap("{\"name\":\"zhangsan\"}");
Assertions.assertEquals(map2.get("name"), "zhangsan");
// 抛异常
Assertions.assertThrows(SaJsonConvertException.class, () -> saJsonTemplate.parseJsonToMap(""));
Assertions.assertThrows(SaJsonConvertException.class, () -> saJsonTemplate.jsonToMap(""));
}
// 测试过滤器拦截器 基础API