diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/application/SaGetValueInterface.java b/sa-token-core/src/main/java/cn/dev33/satoken/application/SaGetValueInterface.java index 7bd20cdc..8b8f3b0f 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/application/SaGetValueInterface.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/application/SaGetValueInterface.java @@ -120,11 +120,8 @@ public interface SaGetValueInterface { */ @SuppressWarnings("unchecked") default T getModel(String key, Class cs, Object defaultValue) { - Object value = get(key); - if(valueIsNull(value)) { - return (T)defaultValue; - } - return SaFoxUtil.getValueByType(value, cs); + T model = getModel(key, cs); + return valueIsNull(model) ? (T)defaultValue : model; } /** diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/dao/SaTokenDao.java b/sa-token-core/src/main/java/cn/dev33/satoken/dao/SaTokenDao.java index 4338c530..2c17c38c 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/dao/SaTokenDao.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/dao/SaTokenDao.java @@ -96,6 +96,14 @@ public interface SaTokenDao { */ Object getObject(String key); + /** + * 获取 Object (指定反序列化类型),如无返空 + * + * @param key 键名称 + * @return object + */ + T getObject(String key, Class classType); + /** * 写入 Object,并设定存活时间 (单位: 秒) * diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/dao/SaTokenDaoDefaultImpl.java b/sa-token-core/src/main/java/cn/dev33/satoken/dao/SaTokenDaoDefaultImpl.java index 6a1cb6df..f90d8a93 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/dao/SaTokenDaoDefaultImpl.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/dao/SaTokenDaoDefaultImpl.java @@ -39,6 +39,12 @@ public class SaTokenDaoDefaultImpl implements SaTokenDaoByStringFollowObject { return timedCache.getObject(key); } + @Override + @SuppressWarnings("unchecked") + public T getObject(String key, Class classType){ + return (T) getObject(key); + } + @Override public void setObject(String key, Object object, long timeout) { timedCache.setObject(key, object, timeout); diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/dao/auto/SaTokenDaoByObjectFollowString.java b/sa-token-core/src/main/java/cn/dev33/satoken/dao/auto/SaTokenDaoByObjectFollowString.java index f2c2a7da..52432970 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/dao/auto/SaTokenDaoByObjectFollowString.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/dao/auto/SaTokenDaoByObjectFollowString.java @@ -39,6 +39,17 @@ public interface SaTokenDaoByObjectFollowString extends SaTokenDaoBySessionFollo return SaManager.getSaSerializerTemplate().stringToObject(jsonString); } + /** + * 获取 Object (指定反序列化类型),如无返空 + * + * @param key 键名称 + * @return object + */ + default T getObject(String key, Class classType) { + String jsonString = get(key); + return SaManager.getSaSerializerTemplate().stringToObject(jsonString, classType); + } + /** * 写入 Object,并设定存活时间 (单位: 秒) * diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/dao/auto/SaTokenDaoBySessionFollowObject.java b/sa-token-core/src/main/java/cn/dev33/satoken/dao/auto/SaTokenDaoBySessionFollowObject.java index a02dba31..47f8bae4 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/dao/auto/SaTokenDaoBySessionFollowObject.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/dao/auto/SaTokenDaoBySessionFollowObject.java @@ -17,6 +17,7 @@ package cn.dev33.satoken.dao.auto; import cn.dev33.satoken.dao.SaTokenDao; import cn.dev33.satoken.session.SaSession; +import cn.dev33.satoken.strategy.SaStrategy; /** * SaTokenDao 次级实现:SaSession 读写跟随 Object 读写 @@ -34,7 +35,7 @@ public interface SaTokenDaoBySessionFollowObject extends SaTokenDao { * @return SaSession */ default SaSession getSession(String sessionId) { - return (SaSession)getObject(sessionId); + return getObject(sessionId, SaStrategy.instance.sessionClassType); } /** diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/json/SaJsonTemplate.java b/sa-token-core/src/main/java/cn/dev33/satoken/json/SaJsonTemplate.java index 2ecc74dd..54a628a1 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/json/SaJsonTemplate.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/json/SaJsonTemplate.java @@ -37,9 +37,21 @@ public interface SaJsonTemplate { * 反序列化:json 字符串 → 对象 * * @param jsonStr / + * @param type / + * @return / + * @param / + */ + T jsonToObject(String jsonStr, Class type); + + /** + * 反序列化:json 字符串 → 对象 (自动判断类型) + * + * @param jsonStr / * @return / */ - Object jsonToObject(String jsonStr); + default Object jsonToObject(String jsonStr) { + return jsonToObject(jsonStr, Object.class); + }; /** * 反序列化:json 字符串 → Map @@ -47,6 +59,8 @@ public interface SaJsonTemplate { * @param jsonStr / * @return / */ - Map jsonToMap(String jsonStr); + default Map jsonToMap(String jsonStr) { + return jsonToObject(jsonStr, Map.class); + }; } diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/json/SaJsonTemplateDefaultImpl.java b/sa-token-core/src/main/java/cn/dev33/satoken/json/SaJsonTemplateDefaultImpl.java index 19a8389b..21d70018 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/json/SaJsonTemplateDefaultImpl.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/json/SaJsonTemplateDefaultImpl.java @@ -42,6 +42,11 @@ public class SaJsonTemplateDefaultImpl implements SaJsonTemplate { throw new NotImplException(ERROR_MESSAGE).setCode(SaErrorCode.CODE_10003); } + @Override + public T jsonToObject(String jsonStr, Class type) { + throw new NotImplException(ERROR_MESSAGE).setCode(SaErrorCode.CODE_10003); + } + @Override public Map jsonToMap(String jsonStr) { throw new NotImplException(ERROR_MESSAGE).setCode(SaErrorCode.CODE_10003); diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/serializer/SaSerializerTemplate.java b/sa-token-core/src/main/java/cn/dev33/satoken/serializer/SaSerializerTemplate.java index 19770ac1..fc51d723 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/serializer/SaSerializerTemplate.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/serializer/SaSerializerTemplate.java @@ -39,6 +39,21 @@ public interface SaSerializerTemplate { */ Object stringToObject(String str); + /** + * 反序列化:字符串 → 对象 (指定类型) + *

+ * 此方法目前仅为 json 序列化实现类 在 反序列化对象 传递类型信息 + *

+ * + * @param str / + * @return / + */ + @SuppressWarnings("unchecked") + default T stringToObject(String str, Class type) { + return (T)stringToObject(str); + }; + + /** * 序列化:对象 -> 字节数组 * diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/serializer/impl/SaSerializerTemplateForJson.java b/sa-token-core/src/main/java/cn/dev33/satoken/serializer/impl/SaSerializerTemplateForJson.java index b3597f7d..ebf30e0d 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/serializer/impl/SaSerializerTemplateForJson.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/serializer/impl/SaSerializerTemplateForJson.java @@ -37,6 +37,11 @@ public class SaSerializerTemplateForJson implements SaSerializerTemplate { return SaManager.getSaJsonTemplate().jsonToObject(str); } + @Override + public T stringToObject(String str, Class type) { + return SaManager.getSaJsonTemplate().jsonToObject(str, type); + } + @Override public byte[] objectToBytes(Object obj) { throw new ApiDisabledException("json 序列化器不支持 Object -> byte[]"); diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/strategy/SaStrategy.java b/sa-token-core/src/main/java/cn/dev33/satoken/strategy/SaStrategy.java index facc8bb7..df436e5c 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/strategy/SaStrategy.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/strategy/SaStrategy.java @@ -101,6 +101,11 @@ public final class SaStrategy { return new SaSession(sessionId); }; + /** + * 反序列化 SaSession 时默认指定的类型 + */ + public volatile Class sessionClassType = SaSession.class; + /** * 判断:集合中是否包含指定元素(模糊匹配) */ 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 3b348d60..ab6aef55 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 @@ -20,6 +20,7 @@ import cn.dev33.satoken.exception.SaTokenException; import java.io.Console; import java.io.UnsupportedEncodingException; +import java.lang.reflect.Field; import java.net.URLDecoder; import java.net.URLEncoder; import java.text.SimpleDateFormat; @@ -376,6 +377,36 @@ public class SaFoxUtil { return (T)obj3; } + /** + * 将 Map 转化为 Object + * @param map / + * @param clazz / + * @return / + * @param / + */ + public static T mapToObject(Map map, Class clazz) { + if(map == null) { + return null; + } + if(clazz == Map.class) { + return (T) map; + } + try { + T obj = clazz.getDeclaredConstructor().newInstance(); + for (Field field : clazz.getDeclaredFields()) { + String fieldName = field.getName(); + if (map.containsKey(fieldName)) { + field.setAccessible(true); + field.set(obj, map.get(fieldName)); + } + } + return obj; + } catch (Exception e) { + throw new RuntimeException("转换失败: " + e.getMessage(), e); + } + } + + /** * 在url上拼接上kv参数并返回 * @param url url diff --git a/sa-token-demo/sa-token-demo-test/pom.xml b/sa-token-demo/sa-token-demo-test/pom.xml index f92c1ca6..14ece5b9 100644 --- a/sa-token-demo/sa-token-demo-test/pom.xml +++ b/sa-token-demo/sa-token-demo-test/pom.xml @@ -62,7 +62,7 @@ cn.dev33 - sa-token-serializer-features + sa-token-fastjson ${sa-token.version} diff --git a/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/satoken/SaTokenConfigure.java b/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/satoken/SaTokenConfigure.java index 36c06081..a133f4b2 100644 --- a/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/satoken/SaTokenConfigure.java +++ b/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/satoken/SaTokenConfigure.java @@ -94,17 +94,17 @@ public class SaTokenConfigure implements WebMvcConfigurer { System.out.println("自定义插件安装钩子函数..."); return SaTokenPluginHolder.instance - .onBeforeInstall(SaTokenPluginForJackson.class, plugin -> { - System.out.println("SaTokenPluginForJackson 插件安装前置钩子..."); - }) - - .onAfterInstall(SaTokenPluginForJackson.class, plugin -> { - System.out.println("SaTokenPluginForJackson 插件安装后置钩子..."); - }) - - .onAfterInstall(SaTokenPluginForJackson.class, plugin -> { - System.out.println("SaTokenPluginForJackson 插件安装后置钩子2..."); - }) +// .onBeforeInstall(SaTokenPluginForJackson.class, plugin -> { +// System.out.println("SaTokenPluginForJackson 插件安装前置钩子..."); +// }) +// +// .onAfterInstall(SaTokenPluginForJackson.class, plugin -> { +// System.out.println("SaTokenPluginForJackson 插件安装后置钩子..."); +// }) +// +// .onAfterInstall(SaTokenPluginForJackson.class, plugin -> { +// System.out.println("SaTokenPluginForJackson 插件安装后置钩子2..."); +// }) // .onInstall(SaTokenPluginForJackson.class, plugin -> { // System.out.println("注册 install 钩子函数后,插件的默认安装行为将不再执行 ..."); diff --git a/sa-token-plugin/sa-token-fastjson/src/main/java/cn/dev33/satoken/json/SaJsonTemplateForFastjson.java b/sa-token-plugin/sa-token-fastjson/src/main/java/cn/dev33/satoken/json/SaJsonTemplateForFastjson.java index 1f4b0612..33ba23c1 100644 --- a/sa-token-plugin/sa-token-fastjson/src/main/java/cn/dev33/satoken/json/SaJsonTemplateForFastjson.java +++ b/sa-token-plugin/sa-token-fastjson/src/main/java/cn/dev33/satoken/json/SaJsonTemplateForFastjson.java @@ -15,11 +15,8 @@ */ package cn.dev33.satoken.json; -import cn.dev33.satoken.session.SaSessionForFastjsonCustomized; import com.alibaba.fastjson.JSON; -import java.util.Map; - /** * JSON 转换器, Fastjson 版实现 * @@ -40,17 +37,8 @@ public class SaJsonTemplateForFastjson implements SaJsonTemplate { * 反序列化:json 字符串 → 对象 */ @Override - public Object jsonToObject(String jsonStr) { - // TODO: 此处待更改,需要让其自动识别类型 - return JSON.parseObject(jsonStr, SaSessionForFastjsonCustomized.class); - } - - /** - * 反序列化:json 字符串 → Map - */ - @Override - public Map jsonToMap(String jsonStr) { - return JSON.parseObject(jsonStr, Map.class); + public T jsonToObject(String jsonStr, Class type) { + return JSON.parseObject(jsonStr, type); } } diff --git a/sa-token-plugin/sa-token-fastjson/src/main/java/cn/dev33/satoken/plugin/SaTokenPluginForFastjson.java b/sa-token-plugin/sa-token-fastjson/src/main/java/cn/dev33/satoken/plugin/SaTokenPluginForFastjson.java index dafe1224..1959d9ba 100644 --- a/sa-token-plugin/sa-token-fastjson/src/main/java/cn/dev33/satoken/plugin/SaTokenPluginForFastjson.java +++ b/sa-token-plugin/sa-token-fastjson/src/main/java/cn/dev33/satoken/plugin/SaTokenPluginForFastjson.java @@ -37,6 +37,9 @@ public class SaTokenPluginForFastjson implements SaTokenPlugin { // 重写 SaSession 生成策略 SaStrategy.instance.createSession = SaSessionForFastjsonCustomized::new; + // 指定 SaSession 类型 + SaStrategy.instance.sessionClassType = SaSessionForFastjsonCustomized.class; + } } \ No newline at end of file diff --git a/sa-token-plugin/sa-token-fastjson/src/main/java/cn/dev33/satoken/session/SaSessionForFastjsonCustomized.java b/sa-token-plugin/sa-token-fastjson/src/main/java/cn/dev33/satoken/session/SaSessionForFastjsonCustomized.java index c82e236a..88f5e6e9 100644 --- a/sa-token-plugin/sa-token-fastjson/src/main/java/cn/dev33/satoken/session/SaSessionForFastjsonCustomized.java +++ b/sa-token-plugin/sa-token-fastjson/src/main/java/cn/dev33/satoken/session/SaSessionForFastjsonCustomized.java @@ -17,6 +17,7 @@ package cn.dev33.satoken.session; import cn.dev33.satoken.util.SaFoxUtil; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; /** * Fastjson 定制版 SaSession,重写类型转换API @@ -52,31 +53,22 @@ public class SaSessionForFastjsonCustomized extends SaSession { */ @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 SaFoxUtil.getValueByType(value, cs); + } + // 为空提前返回 + if(valueIsNull(value)) { + return null; + } + // 如果是 JSONObject 类型直接转,否则先转为 String 再转 + if(value instanceof JSONObject) { + JSONObject jo = (JSONObject) value; + return jo.toJavaObject(cs); + } else { + return JSON.parseObject(value.toString(), cs); } - return JSON.parseObject(getString(key), cs); } } diff --git a/sa-token-plugin/sa-token-jackson/src/main/java/cn/dev33/satoken/json/SaJsonTemplateForJackson.java b/sa-token-plugin/sa-token-jackson/src/main/java/cn/dev33/satoken/json/SaJsonTemplateForJackson.java index f667c10f..34cfce1c 100644 --- a/sa-token-plugin/sa-token-jackson/src/main/java/cn/dev33/satoken/json/SaJsonTemplateForJackson.java +++ b/sa-token-plugin/sa-token-jackson/src/main/java/cn/dev33/satoken/json/SaJsonTemplateForJackson.java @@ -36,7 +36,6 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.format.DateTimeFormatter; -import java.util.Map; /** * JSON 转换器, Jackson 版实现 @@ -110,7 +109,6 @@ public class SaJsonTemplateForJackson implements SaJsonTemplate { return null; } try { - System.out.println("序列化的啥:" + objectMapper.writeValueAsString(obj)); return objectMapper.writeValueAsString(obj); } catch (JsonProcessingException e) { throw new SaJsonConvertException(e); @@ -121,30 +119,12 @@ public class SaJsonTemplateForJackson implements SaJsonTemplate { * 反序列化:json 字符串 → 对象 */ @Override - public Object jsonToObject(String jsonStr) { + public T jsonToObject(String jsonStr, Class type) { if(SaFoxUtil.isEmpty(jsonStr)) { return null; } try { - Object value = objectMapper.readValue(jsonStr, Object.class); - return value; - } catch (JsonProcessingException e) { - throw new SaJsonConvertException(e); - } - } - - /** - * 反序列化:json 字符串 → Map - */ - @Override - public Map jsonToMap(String jsonStr) { - if(SaFoxUtil.isEmpty(jsonStr)) { - return null; - } - try { - @SuppressWarnings("unchecked") - Map map = objectMapper.readValue(jsonStr, Map.class); - return map; + return objectMapper.readValue(jsonStr, type); } catch (JsonProcessingException e) { throw new SaJsonConvertException(e); } diff --git a/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/json/SaJsonTemplateForSnack3.java b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/json/SaJsonTemplateForSnack3.java index 92521830..f40bf566 100644 --- a/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/json/SaJsonTemplateForSnack3.java +++ b/sa-token-starter/sa-token-solon-plugin/src/main/java/cn/dev33/satoken/solon/json/SaJsonTemplateForSnack3.java @@ -18,8 +18,6 @@ package cn.dev33.satoken.solon.json; import cn.dev33.satoken.json.SaJsonTemplate; import org.noear.snack.ONode; -import java.util.Map; - /** * @author noear * @since 2.0 @@ -37,6 +35,14 @@ public class SaJsonTemplateForSnack3 implements SaJsonTemplate { return ONode.stringify(obj); } + /** + * 反序列化:json 字符串 → 对象 + */ + @Override + public T jsonToObject(String jsonStr, Class type) { + return ONode.deserialize(jsonStr, type); + } + /** * 反序列化:json 字符串 → 对象 * @@ -48,15 +54,4 @@ public class SaJsonTemplateForSnack3 implements SaJsonTemplate { return ONode.deserialize(jsonStr); } - /** - * 反序列化:json 字符串 → Map - * - * @param jsonStr / - * @return / - */ - @Override - public Map jsonToMap(String jsonStr) { - return ONode.deserialize(jsonStr, Map.class); - } - }