From 132ad788cbf7e8e304ac2fa6d6341129a4733e9c Mon Sep 17 00:00:00 2001
From: click33 <2393584716@qq.com>
Date: Wed, 19 Oct 2022 07:16:13 +0800
Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=20`sa-token-dao-redis-fastjs?=
=?UTF-8?q?on2`=20=E6=8F=92=E4=BB=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../sa-token-dao-redis-fastjson2/.gitignore | 13 +
.../sa-token-dao-redis-fastjson2/pom.xml | 35 +++
.../dao/SaSessionForFastjson2Customized.java | 76 ++++++
.../satoken/dao/SaTokenDaoRedisFastjson2.java | 246 ++++++++++++++++++
.../main/resources/META-INF/spring.factories | 1 +
5 files changed, 371 insertions(+)
create mode 100644 sa-token-plugin/sa-token-dao-redis-fastjson2/.gitignore
create mode 100644 sa-token-plugin/sa-token-dao-redis-fastjson2/pom.xml
create mode 100644 sa-token-plugin/sa-token-dao-redis-fastjson2/src/main/java/cn/dev33/satoken/dao/SaSessionForFastjson2Customized.java
create mode 100644 sa-token-plugin/sa-token-dao-redis-fastjson2/src/main/java/cn/dev33/satoken/dao/SaTokenDaoRedisFastjson2.java
create mode 100644 sa-token-plugin/sa-token-dao-redis-fastjson2/src/main/resources/META-INF/spring.factories
diff --git a/sa-token-plugin/sa-token-dao-redis-fastjson2/.gitignore b/sa-token-plugin/sa-token-dao-redis-fastjson2/.gitignore
new file mode 100644
index 00000000..8122f47c
--- /dev/null
+++ b/sa-token-plugin/sa-token-dao-redis-fastjson2/.gitignore
@@ -0,0 +1,13 @@
+target/
+
+node_modules/
+bin/
+.settings/
+unpackage/
+.classpath
+.project
+
+.factorypath
+
+.idea/
+.iml
\ No newline at end of file
diff --git a/sa-token-plugin/sa-token-dao-redis-fastjson2/pom.xml b/sa-token-plugin/sa-token-dao-redis-fastjson2/pom.xml
new file mode 100644
index 00000000..7dd9f34d
--- /dev/null
+++ b/sa-token-plugin/sa-token-dao-redis-fastjson2/pom.xml
@@ -0,0 +1,35 @@
+
+
+
+ sa-token-plugin
+ cn.dev33
+ ${revision}
+ ../pom.xml
+
+ 4.0.0
+
+ sa-token-dao-redis-fastjson2
+
+
+
+
+ cn.dev33
+ sa-token-core
+ ${revision}
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+ 2.3.3.RELEASE
+
+
+
+ com.alibaba.fastjson2
+ fastjson2
+ 2.0.15
+
+
+
\ No newline at end of file
diff --git a/sa-token-plugin/sa-token-dao-redis-fastjson2/src/main/java/cn/dev33/satoken/dao/SaSessionForFastjson2Customized.java b/sa-token-plugin/sa-token-dao-redis-fastjson2/src/main/java/cn/dev33/satoken/dao/SaSessionForFastjson2Customized.java
new file mode 100644
index 00000000..8ea39cf2
--- /dev/null
+++ b/sa-token-plugin/sa-token-dao-redis-fastjson2/src/main/java/cn/dev33/satoken/dao/SaSessionForFastjson2Customized.java
@@ -0,0 +1,76 @@
+package cn.dev33.satoken.dao;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.annotation.JSONField;
+
+import cn.dev33.satoken.session.SaSession;
+import cn.dev33.satoken.util.SaFoxUtil;
+
+/**
+ * Fastjson 定制版 SaSession,重写类型转换API
+ *
+ * @author kong
+ * @since 2022-10-19
+ */
+public class SaSessionForFastjson2Customized extends SaSession {
+
+ private static final long serialVersionUID = -7600983549653130681L;
+
+ public SaSessionForFastjson2Customized() {
+ super();
+ }
+
+ /**
+ * 构建一个 SaSession 对象
+ * @param id Session 的 id
+ */
+ public SaSessionForFastjson2Customized(String id) {
+ super(id);
+ }
+
+ /**
+ * 取值 (指定转换类型)
+ * @param 泛型
+ * @param key key
+ * @param cs 指定转换类型
+ * @return 值
+ */
+ @Override
+ public T getModel(String key, Class cs) {
+ if(SaFoxUtil.isBasicType(cs)) {
+ return SaFoxUtil.getValueByType(get(key), cs);
+ }
+ return JSON.parseObject(getString(key), cs);
+ }
+
+ /**
+ * 取值 (指定转换类型, 并指定值为Null时返回的默认值)
+ * @param 泛型
+ * @param key key
+ * @param cs 指定转换类型
+ * @param defaultValue 值为Null时返回的默认值
+ * @return 值
+ */
+ @Override
+ @SuppressWarnings("unchecked")
+ public T getModel(String key, Class cs, Object defaultValue) {
+ Object value = get(key);
+ if(valueIsNull(value)) {
+ return (T)defaultValue;
+ }
+ if(SaFoxUtil.isBasicType(cs)) {
+ return SaFoxUtil.getValueByType(get(key), cs);
+ }
+ return JSON.parseObject(getString(key), cs);
+ }
+
+ /**
+ * 忽略 timeout 字段的序列化
+ */
+ @Override
+ @JSONField(serialize = false)
+ public long getTimeout() {
+ return super.getTimeout();
+ }
+
+}
diff --git a/sa-token-plugin/sa-token-dao-redis-fastjson2/src/main/java/cn/dev33/satoken/dao/SaTokenDaoRedisFastjson2.java b/sa-token-plugin/sa-token-dao-redis-fastjson2/src/main/java/cn/dev33/satoken/dao/SaTokenDaoRedisFastjson2.java
new file mode 100644
index 00000000..0ae0a8b1
--- /dev/null
+++ b/sa-token-plugin/sa-token-dao-redis-fastjson2/src/main/java/cn/dev33/satoken/dao/SaTokenDaoRedisFastjson2.java
@@ -0,0 +1,246 @@
+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;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+import org.springframework.stereotype.Component;
+
+import com.alibaba.fastjson2.JSON;
+
+import cn.dev33.satoken.session.SaSession;
+import cn.dev33.satoken.strategy.SaStrategy;
+import cn.dev33.satoken.util.SaFoxUtil;
+
+/**
+ * Sa-Token持久层接口 [Redis版 (使用JSON字符串进行序列化)]
+ *
+ * @author sikadai
+ *
+ */
+@Component
+public class SaTokenDaoRedisFastjson2 implements SaTokenDao {
+
+ /**
+ * String专用
+ */
+ public StringRedisTemplate stringRedisTemplate;
+
+ /**
+ * Object专用
+ */
+ public StringRedisTemplate objectRedisTemplate;
+
+ /**
+ * 标记:是否已初始化成功
+ */
+ public boolean isInit;
+
+ @Autowired
+ public void init(RedisConnectionFactory connectionFactory) {
+ // 不重复初始化
+ if(this.isInit) {
+ return;
+ }
+
+ // 重写 SaSession 生成策略
+ SaStrategy.me.createSession = (sessionId) -> new SaSessionForFastjson2Customized(sessionId);
+ System.out.println("------------------ 执行了");
+
+ // 指定相应的序列化方案
+ StringRedisSerializer keySerializer = new StringRedisSerializer();
+ StringRedisSerializer valueSerializer = new StringRedisSerializer();
+ // 构建StringRedisTemplate
+ StringRedisTemplate stringTemplate = new StringRedisTemplate();
+ stringTemplate.setConnectionFactory(connectionFactory);
+ stringTemplate.afterPropertiesSet();
+ // 构建RedisTemplate
+ StringRedisTemplate template = new StringRedisTemplate();
+ template.setConnectionFactory(connectionFactory);
+ template.setKeySerializer(keySerializer);
+ template.setHashKeySerializer(keySerializer);
+ template.setValueSerializer(valueSerializer);
+ template.setHashValueSerializer(valueSerializer);
+ template.afterPropertiesSet();
+
+ // 开始初始化相关组件
+ this.stringRedisTemplate = stringTemplate;
+ this.objectRedisTemplate = template;
+ this.isInit = true;
+ }
+
+
+ /**
+ * 获取Value,如无返空
+ */
+ @Override
+ public String get(String key) {
+ return stringRedisTemplate.opsForValue().get(key);
+ }
+
+ /**
+ * 写入Value,并设定存活时间 (单位: 秒)
+ */
+ @Override
+ public void set(String key, String value, long timeout) {
+ if(timeout == 0 || timeout <= SaTokenDao.NOT_VALUE_EXPIRE) {
+ return;
+ }
+ // 判断是否为永不过期
+ if(timeout == SaTokenDao.NEVER_EXPIRE) {
+ stringRedisTemplate.opsForValue().set(key, value);
+ } else {
+ stringRedisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);
+ }
+ }
+
+ /**
+ * 修改指定key-value键值对 (过期时间不变)
+ */
+ @Override
+ public void update(String key, String value) {
+ long expire = getTimeout(key);
+ // -2 = 无此键
+ if(expire == SaTokenDao.NOT_VALUE_EXPIRE) {
+ return;
+ }
+ this.set(key, value, expire);
+ }
+
+ /**
+ * 删除Value
+ */
+ @Override
+ public void delete(String key) {
+ stringRedisTemplate.delete(key);
+ }
+
+ /**
+ * 获取Value的剩余存活时间 (单位: 秒)
+ */
+ @Override
+ public long getTimeout(String key) {
+ return stringRedisTemplate.getExpire(key);
+ }
+
+ /**
+ * 修改Value的剩余存活时间 (单位: 秒)
+ */
+ @Override
+ public void updateTimeout(String key, long timeout) {
+ // 判断是否想要设置为永久
+ if(timeout == SaTokenDao.NEVER_EXPIRE) {
+ long expire = getTimeout(key);
+ if(expire == SaTokenDao.NEVER_EXPIRE) {
+ // 如果其已经被设置为永久,则不作任何处理
+ } else {
+ // 如果尚未被设置为永久,那么再次set一次
+ this.set(key, this.get(key), timeout);
+ }
+ return;
+ }
+ stringRedisTemplate.expire(key, timeout, TimeUnit.SECONDS);
+ }
+
+
+ /**
+ * 获取Object,如无返空
+ */
+ @Override
+ public Object getObject(String key) {
+ return objectRedisTemplate.opsForValue().get(key);
+ }
+
+ @Override
+ public SaSession getSession(String sessionId) {
+ Object obj = getObject(sessionId);
+ if (obj == null) {
+ return null;
+ }
+ return JSON.parseObject(obj.toString(), SaSessionForFastjson2Customized.class);
+ }
+
+ /**
+ * 写入Object,并设定存活时间 (单位: 秒)
+ */
+ @Override
+ public void setObject(String key, Object object, long timeout) {
+ if(timeout == 0 || timeout <= SaTokenDao.NOT_VALUE_EXPIRE) {
+ return;
+ }
+ String toValue = JSON.toJSONString(object);
+ // 判断是否为永不过期
+ if(timeout == SaTokenDao.NEVER_EXPIRE) {
+ objectRedisTemplate.opsForValue().set(key, toValue);
+ } else {
+ objectRedisTemplate.opsForValue().set(key, toValue, timeout, TimeUnit.SECONDS);
+ }
+ }
+
+ /**
+ * 更新Object (过期时间不变)
+ */
+ @Override
+ public void updateObject(String key, Object object) {
+ long expire = getObjectTimeout(key);
+ // -2 = 无此键
+ if(expire == SaTokenDao.NOT_VALUE_EXPIRE) {
+ return;
+ }
+ this.setObject(key, object, expire);
+ }
+
+ /**
+ * 删除Object
+ */
+ @Override
+ public void deleteObject(String key) {
+ objectRedisTemplate.delete(key);
+ }
+
+ /**
+ * 获取Object的剩余存活时间 (单位: 秒)
+ */
+ @Override
+ public long getObjectTimeout(String key) {
+ return objectRedisTemplate.getExpire(key);
+ }
+
+ /**
+ * 修改Object的剩余存活时间 (单位: 秒)
+ */
+ @Override
+ public void updateObjectTimeout(String key, long timeout) {
+ // 判断是否想要设置为永久
+ if(timeout == SaTokenDao.NEVER_EXPIRE) {
+ long expire = getObjectTimeout(key);
+ if(expire == SaTokenDao.NEVER_EXPIRE) {
+ // 如果其已经被设置为永久,则不作任何处理
+ } else {
+ // 如果尚未被设置为永久,那么再次set一次
+ this.setObject(key, this.getObject(key), timeout);
+ }
+ return;
+ }
+ objectRedisTemplate.expire(key, timeout, TimeUnit.SECONDS);
+ }
+
+
+
+ /**
+ * 搜索数据
+ */
+ @Override
+ public List searchData(String prefix, String keyword, int start, int size, boolean sortType) {
+ Set keys = stringRedisTemplate.keys(prefix + "*" + keyword + "*");
+ List list = new ArrayList(keys);
+ return SaFoxUtil.searchList(list, start, size, sortType);
+ }
+
+
+}
diff --git a/sa-token-plugin/sa-token-dao-redis-fastjson2/src/main/resources/META-INF/spring.factories b/sa-token-plugin/sa-token-dao-redis-fastjson2/src/main/resources/META-INF/spring.factories
new file mode 100644
index 00000000..8774edc6
--- /dev/null
+++ b/sa-token-plugin/sa-token-dao-redis-fastjson2/src/main/resources/META-INF/spring.factories
@@ -0,0 +1 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.dev33.satoken.dao.SaTokenDaoRedisFastjson2
\ No newline at end of file