From 1c5653dae3767c517372ef0a3d1edbe95c737e2c Mon Sep 17 00:00:00 2001
From: click33 <2393584716@qq.com>
Date: Wed, 19 Oct 2022 07:15:59 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20sa-token-dao-redis-fastjso?=
=?UTF-8?q?n=20=E6=8F=92=E4=BB=B6=20`session.getModel`=20=E6=97=A0?=
=?UTF-8?q?=E6=B3=95=E5=8F=8D=E5=BA=8F=E5=88=97=E5=8C=96=E5=AE=9E=E4=BD=93?=
=?UTF-8?q?=E7=B1=BB=E7=9A=84=E9=97=AE=E9=A2=98=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../java/cn/dev33/satoken/util/SaFoxUtil.java | 21 +++++
.../src/main/java/com/pj/model/SysUser.java | 84 +++++++++++++++++++
.../main/java/com/pj/test/TestController.java | 21 +++--
sa-token-doc/start/new-version.md | 17 ++++
sa-token-doc/use/session.md | 6 +-
sa-token-plugin/pom.xml | 1 +
.../sa-token-dao-redis-fastjson/pom.xml | 1 +
.../dao/SaSessionForFastjsonCustomized.java | 76 +++++++++++++++++
.../satoken/dao/SaTokenDaoRedisFastjson.java | 23 +++--
.../satoken/dao/SaTokenDaoRedisJackson.java | 4 +-
.../cn/dev33/satoken/dao/SaTokenDaoRedis.java | 2 +-
.../satoken/core/util/SaFoxUtilTest.java | 31 +++++++
12 files changed, 268 insertions(+), 19 deletions(-)
create mode 100644 sa-token-demo/sa-token-demo-test/src/main/java/com/pj/model/SysUser.java
create mode 100644 sa-token-doc/start/new-version.md
create mode 100644 sa-token-plugin/sa-token-dao-redis-fastjson/src/main/java/cn/dev33/satoken/dao/SaSessionForFastjsonCustomized.java
diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/util/SaFoxUtil.java b/sa-token-core/src/main/java/cn/dev33/satoken/util/SaFoxUtil.java
index d20cbca7..c42be338 100644
--- a/sa-token-core/src/main/java/cn/dev33/satoken/util/SaFoxUtil.java
+++ b/sa-token-core/src/main/java/cn/dev33/satoken/util/SaFoxUtil.java
@@ -208,6 +208,25 @@ public class SaFoxUtil {
// 正则匹配
return Pattern.matches(patt.replaceAll("\\*", ".*"), str);
}
+
+ /**
+ * 判断类型是否为8大包装类型
+ * @param cs /
+ * @return /
+ */
+ public static boolean isWrapperType(Class> cs) {
+ return cs == Integer.class || cs == Short.class || cs == Long.class || cs == Byte.class
+ || cs == Float.class || cs == Double.class || cs == Boolean.class || cs == Character.class;
+ }
+
+ /**
+ * 判断类型是否为基础类型:8大基本数据类型、8大包装类、String
+ * @param cs /
+ * @return /
+ */
+ public static boolean isBasicType(Class> cs) {
+ return cs.isPrimitive() || isWrapperType(cs) || cs == String.class;
+ }
/**
* 将指定值转化为指定类型
@@ -241,6 +260,8 @@ public class SaFoxUtil {
obj3 = Double.valueOf(obj2);
} else if (cs.equals(boolean.class) || cs.equals(Boolean.class)) {
obj3 = Boolean.valueOf(obj2);
+ } else if (cs.equals(char.class) || cs.equals(Character.class)) {
+ obj3 = obj2.charAt(0);
} else {
obj3 = (T)obj;
}
diff --git a/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/model/SysUser.java b/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/model/SysUser.java
new file mode 100644
index 00000000..3e3a2f22
--- /dev/null
+++ b/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/model/SysUser.java
@@ -0,0 +1,84 @@
+package com.pj.model;
+
+/**
+ * User 实体类
+ *
+ * @author kong
+ * @since 2022-10-15
+ */
+public class SysUser {
+
+ public SysUser() {
+ }
+
+ public SysUser(long id, String name, int age) {
+ super();
+ this.id = id;
+ this.name = name;
+ this.age = age;
+ }
+
+
+ /**
+ * 用户id
+ */
+ private long id;
+
+ /**
+ * 用户名称
+ */
+ private String name;
+
+ /**
+ * 用户年龄
+ */
+ private int age;
+
+ /**
+ * @return id
+ */
+ public long getId() {
+ return id;
+ }
+
+ /**
+ * @param id 要设置的 id
+ */
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ /**
+ * @return name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @param name 要设置的 name
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * @return age
+ */
+ public int getAge() {
+ return age;
+ }
+
+ /**
+ * @param age 要设置的 age
+ */
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ @Override
+ public String toString() {
+ return "SysUser [id=" + id + ", name=" + name + ", age=" + age + "]";
+ }
+
+}
diff --git a/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/test/TestController.java b/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/test/TestController.java
index 6c5b3412..dc480dfe 100644
--- a/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/test/TestController.java
+++ b/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/test/TestController.java
@@ -1,9 +1,11 @@
package com.pj.test;
import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
-import com.pj.util.AjaxJson;
+import cn.dev33.satoken.stp.StpUtil;
+import cn.dev33.satoken.util.SaResult;
/**
* 测试专用Controller
@@ -14,17 +16,26 @@ import com.pj.util.AjaxJson;
@RequestMapping("/test/")
public class TestController {
+ // 测试登录 ---- http://localhost:8081/test/login
+ @RequestMapping("login")
+ public SaResult login(@RequestParam(defaultValue = "10001") long id) {
+ StpUtil.login(id);
+ return SaResult.ok("登录成功");
+ }
+
+
// 测试 浏览器访问: http://localhost:8081/test/test
@RequestMapping("test")
- public AjaxJson test() {
+ public SaResult test() {
System.out.println("------------进来了");
- return AjaxJson.getSuccess();
+ // 返回
+ return SaResult.data("");
}
// 测试 浏览器访问: http://localhost:8081/test/test2
@RequestMapping("test2")
- public AjaxJson test2() {
- return AjaxJson.getSuccess();
+ public SaResult test2() {
+ return SaResult.ok();
}
}
diff --git a/sa-token-doc/start/new-version.md b/sa-token-doc/start/new-version.md
new file mode 100644
index 00000000..217dac58
--- /dev/null
+++ b/sa-token-doc/start/new-version.md
@@ -0,0 +1,17 @@
+# Sa-Token 最新版本
+
+在线文档:[https://sa-token.dev33.cn/](https://sa-token.dev33.cn/)
+
+---
+
+正式版最新版本:
+``` xml
+
+
+ cn.dev33
+ sa-token-spring-boot-starter
+ 1.31.0
+
+```
+
+
diff --git a/sa-token-doc/use/session.md b/sa-token-doc/use/session.md
index a0567380..7b60583d 100644
--- a/sa-token-doc/use/session.md
+++ b/sa-token-doc/use/session.md
@@ -140,10 +140,10 @@ session.logout();
``` java
@PostMapping("/resetPoints")
public void reset(HttpSession session) {
- // 在HttpSession上写入一个值
+ // 在 HttpSession 上写入一个值
session.setAttribute("name", 66);
- // 在SaSession进行取值
- System.out.println(StpUtil.getSession().getAttribute("name")); // 输出null
+ // 在 SaSession 进行取值
+ System.out.println(StpUtil.getSession().get("name")); // 输出null
}
```
**要点:**
diff --git a/sa-token-plugin/pom.xml b/sa-token-plugin/pom.xml
index 127b8180..72d6e107 100644
--- a/sa-token-plugin/pom.xml
+++ b/sa-token-plugin/pom.xml
@@ -22,6 +22,7 @@
sa-token-dao-redis
sa-token-dao-redis-jackson
sa-token-dao-redis-fastjson
+ sa-token-dao-redis-fastjson2
sa-token-dao-redisx
sa-token-dialect-thymeleaf
sa-token-sso
diff --git a/sa-token-plugin/sa-token-dao-redis-fastjson/pom.xml b/sa-token-plugin/sa-token-dao-redis-fastjson/pom.xml
index 97a4d7f6..8f0538d2 100644
--- a/sa-token-plugin/sa-token-dao-redis-fastjson/pom.xml
+++ b/sa-token-plugin/sa-token-dao-redis-fastjson/pom.xml
@@ -25,6 +25,7 @@
spring-boot-starter-data-redis
2.3.3.RELEASE
+
com.alibaba
fastjson
diff --git a/sa-token-plugin/sa-token-dao-redis-fastjson/src/main/java/cn/dev33/satoken/dao/SaSessionForFastjsonCustomized.java b/sa-token-plugin/sa-token-dao-redis-fastjson/src/main/java/cn/dev33/satoken/dao/SaSessionForFastjsonCustomized.java
new file mode 100644
index 00000000..1c072fbc
--- /dev/null
+++ b/sa-token-plugin/sa-token-dao-redis-fastjson/src/main/java/cn/dev33/satoken/dao/SaSessionForFastjsonCustomized.java
@@ -0,0 +1,76 @@
+package cn.dev33.satoken.dao;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.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 SaSessionForFastjsonCustomized extends SaSession {
+
+ private static final long serialVersionUID = -7600983549653130681L;
+
+ public SaSessionForFastjsonCustomized() {
+ super();
+ }
+
+ /**
+ * 构建一个 SaSession 对象
+ * @param id Session 的 id
+ */
+ public SaSessionForFastjsonCustomized(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-fastjson/src/main/java/cn/dev33/satoken/dao/SaTokenDaoRedisFastjson.java b/sa-token-plugin/sa-token-dao-redis-fastjson/src/main/java/cn/dev33/satoken/dao/SaTokenDaoRedisFastjson.java
index ff68bdde..f61828d8 100644
--- a/sa-token-plugin/sa-token-dao-redis-fastjson/src/main/java/cn/dev33/satoken/dao/SaTokenDaoRedisFastjson.java
+++ b/sa-token-plugin/sa-token-dao-redis-fastjson/src/main/java/cn/dev33/satoken/dao/SaTokenDaoRedisFastjson.java
@@ -1,18 +1,21 @@
package cn.dev33.satoken.dao;
-import cn.dev33.satoken.session.SaSession;
-import cn.dev33.satoken.util.SaFoxUtil;
-import com.alibaba.fastjson.JSON;
+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 java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
+import com.alibaba.fastjson.JSON;
+
+import cn.dev33.satoken.session.SaSession;
+import cn.dev33.satoken.strategy.SaStrategy;
+import cn.dev33.satoken.util.SaFoxUtil;
/**
* Sa-Token持久层接口 [Redis版 (使用JSON字符串进行序列化)]
@@ -44,6 +47,10 @@ public class SaTokenDaoRedisFastjson implements SaTokenDao {
if(this.isInit) {
return;
}
+
+ // 重写 SaSession 生成策略
+ SaStrategy.me.createSession = (sessionId) -> new SaSessionForFastjsonCustomized(sessionId);
+ System.out.println("------------------ 执行了");
// 指定相应的序列化方案
StringRedisSerializer keySerializer = new StringRedisSerializer();
@@ -155,7 +162,7 @@ public class SaTokenDaoRedisFastjson implements SaTokenDao {
if (obj == null) {
return null;
}
- return JSON.parseObject(obj.toString(), SaSession.class);
+ return JSON.parseObject(obj.toString(), SaSessionForFastjsonCustomized.class);
}
/**
diff --git a/sa-token-plugin/sa-token-dao-redis-jackson/src/main/java/cn/dev33/satoken/dao/SaTokenDaoRedisJackson.java b/sa-token-plugin/sa-token-dao-redis-jackson/src/main/java/cn/dev33/satoken/dao/SaTokenDaoRedisJackson.java
index d81207f5..538bbe40 100644
--- a/sa-token-plugin/sa-token-dao-redis-jackson/src/main/java/cn/dev33/satoken/dao/SaTokenDaoRedisJackson.java
+++ b/sa-token-plugin/sa-token-dao-redis-jackson/src/main/java/cn/dev33/satoken/dao/SaTokenDaoRedisJackson.java
@@ -32,7 +32,7 @@ import cn.dev33.satoken.strategy.SaStrategy;
import cn.dev33.satoken.util.SaFoxUtil;
/**
- * Sa-Token持久层接口 [Redis版] (使用 jackson 序列化方式)
+ * Sa-Token 持久层实现 [Redis存储、Jackson序列化]
*
* @author kong
*
@@ -97,7 +97,7 @@ public class SaTokenDaoRedisJackson implements SaTokenDao {
timeModule.addSerializer(new LocalTimeSerializer(TIME_FORMATTER));
timeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(TIME_FORMATTER));
this.objectMapper.registerModule(timeModule);
- // 重写Session生成策略
+ // 重写 SaSession 生成策略
SaStrategy.me.createSession = (sessionId) -> new SaSessionForJacksonCustomized(sessionId);
} catch (Exception e) {
System.err.println(e.getMessage());
diff --git a/sa-token-plugin/sa-token-dao-redis/src/main/java/cn/dev33/satoken/dao/SaTokenDaoRedis.java b/sa-token-plugin/sa-token-dao-redis/src/main/java/cn/dev33/satoken/dao/SaTokenDaoRedis.java
index 66056334..7bda2fa7 100644
--- a/sa-token-plugin/sa-token-dao-redis/src/main/java/cn/dev33/satoken/dao/SaTokenDaoRedis.java
+++ b/sa-token-plugin/sa-token-dao-redis/src/main/java/cn/dev33/satoken/dao/SaTokenDaoRedis.java
@@ -16,7 +16,7 @@ import org.springframework.stereotype.Component;
import cn.dev33.satoken.util.SaFoxUtil;
/**
- * Sa-Token持久层接口 [Redis版 (使用JDK默认序列化方式)]
+ * Sa-Token 持久层实现 [Redis存储、JDK默认序列化]
*
* @author kong
*
diff --git a/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/util/SaFoxUtilTest.java b/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/util/SaFoxUtilTest.java
index 4c2f9404..f8e7baa6 100644
--- a/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/util/SaFoxUtilTest.java
+++ b/sa-token-test/sa-token-springboot-test/src/test/java/cn/dev33/satoken/core/util/SaFoxUtilTest.java
@@ -6,6 +6,7 @@ import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@@ -108,6 +109,34 @@ public class SaFoxUtilTest {
Assertions.assertFalse(SaFoxUtil.vagueMatch("hello*", null));
}
+ @Test
+ public void isWrapperType() {
+ Assertions.assertTrue(SaFoxUtil.isWrapperType(Integer.class));
+ Assertions.assertTrue(SaFoxUtil.isWrapperType(Short.class));
+ Assertions.assertTrue(SaFoxUtil.isWrapperType(Long.class));
+ Assertions.assertTrue(SaFoxUtil.isWrapperType(Byte.class));
+ Assertions.assertTrue(SaFoxUtil.isWrapperType(Float.class));
+ Assertions.assertTrue(SaFoxUtil.isWrapperType(Double.class));
+ Assertions.assertTrue(SaFoxUtil.isWrapperType(Boolean.class));
+ Assertions.assertTrue(SaFoxUtil.isWrapperType(Character.class));
+
+ Assertions.assertFalse(SaFoxUtil.isWrapperType(int.class));
+ Assertions.assertFalse(SaFoxUtil.isWrapperType(long.class));
+ Assertions.assertFalse(SaFoxUtil.isWrapperType(Object.class));
+ }
+
+ @Test
+ public void isBasicType() {
+ Assertions.assertTrue(SaFoxUtil.isBasicType(int.class));
+ Assertions.assertTrue(SaFoxUtil.isBasicType(Integer.class));
+ Assertions.assertTrue(SaFoxUtil.isBasicType(long.class));
+ Assertions.assertTrue(SaFoxUtil.isBasicType(Long.class));
+ Assertions.assertTrue(SaFoxUtil.isBasicType(String.class));
+
+ Assertions.assertFalse(SaFoxUtil.isBasicType(List.class));
+ Assertions.assertFalse(SaFoxUtil.isBasicType(Map.class));
+ }
+
@Test
public void getValueByType() {
// 基础类型,转换
@@ -125,6 +154,8 @@ public class SaFoxUtilTest {
Assertions.assertEquals(SaFoxUtil.getValueByType("1", Double.class), 1.0);
Assertions.assertEquals(SaFoxUtil.getValueByType("1", boolean.class), false);
Assertions.assertEquals(SaFoxUtil.getValueByType("1", Boolean.class), false);
+ Assertions.assertEquals(SaFoxUtil.getValueByType("1", char.class), '1');
+ Assertions.assertEquals(SaFoxUtil.getValueByType("1", Character.class), '1');
Assertions.assertEquals(SaFoxUtil.getValueByType(1, String.class), "1");
// 复杂类型,还原