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"); // 复杂类型,还原