From e6dd8507528aa908e7fd188af9e7570db93be253 Mon Sep 17 00:00:00 2001 From: click33 <2393584716@qq.com> Date: Thu, 20 Feb 2025 18:38:22 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=20JSON=20?= =?UTF-8?q?=E8=BD=AC=E6=8D=A2=E5=99=A8=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/dev33/satoken/json/SaJsonTemplate.java | 25 +++++--- .../json/SaJsonTemplateDefaultImpl.java | 13 ++-- .../java/cn/dev33/satoken/util/SaResult.java | 2 +- .../src/main/java/com/pj/model/SysRole.java | 64 +++++++++++++++++++ .../src/main/java/com/pj/model/SysUser.java | 23 ++++++- .../solon/json/SaJsonTemplateForSnack3.java | 33 ++++++++-- .../satoken/error/SaSpringBootErrorCode.java | 3 + .../spring/json/SaJsonTemplateForJackson.java | 51 +++++++++++++-- 8 files changed, 190 insertions(+), 24 deletions(-) create mode 100644 sa-token-demo/sa-token-demo-test/src/main/java/com/pj/model/SysRole.java 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 4341c416..2ecc74dd 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 @@ -26,18 +26,27 @@ import java.util.Map; public interface SaJsonTemplate { /** - * 将任意对象序列化为 json 字符串 + * 序列化:对象 -> json 字符串 * - * @param obj 对象 - * @return 转换后的 json 字符串 + * @param obj / + * @return / */ - String toJsonString(Object obj); + String objectToJson(Object obj); /** - * 解析 json 字符串为 map 对象 - * @param jsonStr json 字符串 - * @return map 对象 + * 反序列化:json 字符串 → 对象 + * + * @param jsonStr / + * @return / */ - Map parseJsonToMap(String jsonStr); + Object jsonToObject(String jsonStr); + + /** + * 反序列化:json 字符串 → Map + * + * @param jsonStr / + * @return / + */ + Map jsonToMap(String jsonStr); } 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 7a9dd19c..19a8389b 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 @@ -15,11 +15,11 @@ */ package cn.dev33.satoken.json; -import java.util.Map; - import cn.dev33.satoken.error.SaErrorCode; import cn.dev33.satoken.exception.NotImplException; +import java.util.Map; + /** * JSON 转换器,默认实现类 * @@ -33,12 +33,17 @@ public class SaJsonTemplateDefaultImpl implements SaJsonTemplate { public static final String ERROR_MESSAGE = "未实现具体的 json 转换器"; @Override - public String toJsonString(Object obj) { + public String objectToJson(Object obj) { throw new NotImplException(ERROR_MESSAGE).setCode(SaErrorCode.CODE_10003); } @Override - public Map parseJsonToMap(String jsonStr) { + public Object jsonToObject(String jsonStr) { + 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/util/SaResult.java b/sa-token-core/src/main/java/cn/dev33/satoken/util/SaResult.java index 4d70c980..769dedd6 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/util/SaResult.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/util/SaResult.java @@ -159,7 +159,7 @@ public class SaResult extends LinkedHashMap implements Serializa * @return 对象自身 */ public SaResult setJsonString(String jsonString) { - Map map = SaManager.getSaJsonTemplate().parseJsonToMap(jsonString); + Map map = SaManager.getSaJsonTemplate().jsonToMap(jsonString); return setMap(map); } diff --git a/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/model/SysRole.java b/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/model/SysRole.java new file mode 100644 index 00000000..9048c0e7 --- /dev/null +++ b/sa-token-demo/sa-token-demo-test/src/main/java/com/pj/model/SysRole.java @@ -0,0 +1,64 @@ +package com.pj.model; + +/** + * Role 实体类 + * + * @author click33 + * @since 2022-10-15 + */ +public class SysRole { +// +// public SysRole() { +// } +// +// public SysRole(long id, String name) { +// super(); +// this.id = id; +// this.name = name; +// } +// +// +// /** +// * 角色id +// */ +// private long id; +// +// /** +// * 角色名称 +// */ +// private String name; +// +// /** +// * @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; +// } +// +// @Override +// public String toString() { +// return "SysRole [id=" + id + ", name=" + name + "]"; +// } +// +} 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 index 8291aee7..b130f009 100644 --- 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 @@ -34,6 +34,11 @@ public class SysUser { */ private int age; + /** + * 用户角色 + */ + private SysRole role; + /** * @return id */ @@ -76,9 +81,23 @@ public class SysUser { this.age = age; } + public SysRole getRole() { + return role; + } + + public SysUser setRole(SysRole role) { + this.role = role; + return this; + } + @Override public String toString() { - return "SysUser [id=" + id + ", name=" + name + ", age=" + age + "]"; + return "SysUser{" + + "id=" + id + + ", name='" + name + '\'' + + ", age=" + age + + ", role=" + role + + '}'; } - + } 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 0eadd0ad..92521830 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 @@ -25,13 +25,38 @@ import java.util.Map; * @since 2.0 */ public class SaJsonTemplateForSnack3 implements SaJsonTemplate { + + /** + * 序列化:对象 -> json 字符串 + * + * @param obj / + * @return / + */ @Override - public String toJsonString(Object o) { - return ONode.stringify(o); + public String objectToJson(Object obj) { + return ONode.stringify(obj); } + /** + * 反序列化:json 字符串 → 对象 + * + * @param jsonStr / + * @return / + */ @Override - public Map parseJsonToMap(String s) { - return ONode.deserialize(s, Map.class); + public Object jsonToObject(String jsonStr) { + return ONode.deserialize(jsonStr); } + + /** + * 反序列化:json 字符串 → Map + * + * @param jsonStr / + * @return / + */ + @Override + public Map jsonToMap(String jsonStr) { + return ONode.deserialize(jsonStr, Map.class); + } + } diff --git a/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/error/SaSpringBootErrorCode.java b/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/error/SaSpringBootErrorCode.java index 367ca64c..dee05007 100644 --- a/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/error/SaSpringBootErrorCode.java +++ b/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/error/SaSpringBootErrorCode.java @@ -32,6 +32,9 @@ public interface SaSpringBootErrorCode { /** JSON 字符串转 Map 失败 */ int CODE_20104 = 20104; + /** JSON 字符串转 Object 失败 */ + int CODE_20106 = 20106; + /** 默认的 Filter 异常处理函数 */ int CODE_20105 = 20105; diff --git a/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/json/SaJsonTemplateForJackson.java b/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/json/SaJsonTemplateForJackson.java index bc21de3d..4233c377 100644 --- a/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/json/SaJsonTemplateForJackson.java +++ b/sa-token-starter/sa-token-spring-boot-autoconfig/src/main/java/cn/dev33/satoken/spring/json/SaJsonTemplateForJackson.java @@ -18,8 +18,12 @@ package cn.dev33.satoken.spring.json; import cn.dev33.satoken.error.SaSpringBootErrorCode; import cn.dev33.satoken.exception.SaJsonConvertException; import cn.dev33.satoken.json.SaJsonTemplate; +import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator; +import com.fasterxml.jackson.databind.jsontype.PolymorphicTypeValidator; import java.util.Map; @@ -36,23 +40,60 @@ public class SaJsonTemplateForJackson implements SaJsonTemplate { */ public ObjectMapper objectMapper = new ObjectMapper(); + public SaJsonTemplateForJackson() { + + // 1、使 objectMapper 序列化时带上类型信息,以便该 json 字符串可以成功反序列化 + // 构建反序列化限制器,此处可以限制只允许指定类型或指定包下的类型才可以反序列化,此处指定所有类型都可以反序列化 + PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder() + // 允许所有子类型反序列化(即反序列化时遇到的类) + .allowIfSubType(Object.class) + // 允许所有基类型反序列化(如 Object、自定义抽象类) + .allowIfBaseType(Object.class) + .build(); + // 启用全局默认类型(嵌入类型信息) + objectMapper.activateDefaultTyping( + ptv, + // 对非 final 类嵌入类型信息 + ObjectMapper.DefaultTyping.NON_FINAL, + // 类型信息以属性形式存在("@class") + JsonTypeInfo.As.PROPERTY + ); + + // 2、使空 bean 在序列化时也能记录类型信息,而不是只序列化成 {} + objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + + } + /** - * 将任意对象转换为 json 字符串 + * 序列化:对象 -> json 字符串 */ @Override - public String toJsonString(Object obj) { + public String objectToJson(Object obj) { try { return objectMapper.writeValueAsString(obj); } catch (JsonProcessingException e) { throw new SaJsonConvertException(e).setCode(SaSpringBootErrorCode.CODE_20103); } } - + /** - * 将 json 字符串解析为 Map + * 反序列化:json 字符串 → 对象 */ @Override - public Map parseJsonToMap(String jsonStr) { + public Object jsonToObject(String jsonStr) { + try { + Object value = objectMapper.readValue(jsonStr, Object.class); + return value; + } catch (JsonProcessingException e) { + throw new SaJsonConvertException(e).setCode(SaSpringBootErrorCode.CODE_20106); + } + } + + /** + * 反序列化:json 字符串 → Map + */ + @Override + public Map jsonToMap(String jsonStr) { try { @SuppressWarnings("unchecked") Map map = objectMapper.readValue(jsonStr, Map.class);