From 64a04fdfd1dac71f8b4cc18e0cb21060e45fed82 Mon Sep 17 00:00:00 2001 From: Looly Date: Tue, 1 Oct 2024 11:00:05 +0800 Subject: [PATCH] fix code --- .../dromara/hutool/json/InternalJSONUtil.java | 2 +- .../java/org/dromara/hutool/json/JSON.java | 32 ++-- .../org/dromara/hutool/json/JSONArray.java | 4 +- .../org/dromara/hutool/json/JSONFactory.java | 16 +- .../org/dromara/hutool/json/JSONObject.java | 6 +- .../hutool/json/serializer/JSONMapper.java | 148 ++++++++---------- .../json/serializer/TypeAdapterManager.java | 2 +- .../impl/CharSequenceTypeAdapter.java | 40 ++++- ...er.java => JSONPrimitiveDeserializer.java} | 23 +-- .../dromara/hutool/json/jmh/JsonPutJmh.java | 4 +- 10 files changed, 133 insertions(+), 144 deletions(-) rename hutool-json/src/main/java/org/dromara/hutool/json/serializer/impl/{JSONPrimitiveTypeAdapter.java => JSONPrimitiveDeserializer.java} (68%) diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/InternalJSONUtil.java b/hutool-json/src/main/java/org/dromara/hutool/json/InternalJSONUtil.java index d0444b6e6..b299d805c 100644 --- a/hutool-json/src/main/java/org/dromara/hutool/json/InternalJSONUtil.java +++ b/hutool-json/src/main/java/org/dromara/hutool/json/InternalJSONUtil.java @@ -117,7 +117,7 @@ public final class InternalJSONUtil { .setIgnoreError(config.isIgnoreError()) .setIgnoreNullValue(config.isIgnoreNullValue()) .setTransientSupport(config.isTransientSupport()) - .setConverter((targetType, value) -> mapper.map(value)); + .setConverter((targetType, value) -> mapper.toJSON(value)); } /** diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/JSON.java b/hutool-json/src/main/java/org/dromara/hutool/json/JSON.java index e490ad098..3dcfdbf53 100644 --- a/hutool-json/src/main/java/org/dromara/hutool/json/JSON.java +++ b/hutool-json/src/main/java/org/dromara/hutool/json/JSON.java @@ -44,6 +44,22 @@ public interface JSON extends Serializable { */ JSONFactory getFactory(); + /** + * JSON大小,对于JSONObject,是键值对的多少,JSONArray则是元素的个数,JSON原始数据为1 + * + * @return 大小 + */ + int size(); + + /** + * 将JSON内容写入Writer
+ * Warning: This method assumes that the data structure is acyclical. + * + * @param writer writer + * @throws JSONException JSON相关异常 + */ + void write(JSONWriter writer) throws JSONException; + /** * 获取JSON配置 * @@ -54,13 +70,6 @@ public interface JSON extends Serializable { return getFactory().getConfig(); } - /** - * JSON大小,对于JSONObject,是键值对的多少,JSONArray则是元素的个数,JSON原始数据为1 - * - * @return 大小 - */ - int size(); - /** * 判断JSON是否为空,即大小为0 * @@ -244,15 +253,6 @@ public interface JSON extends Serializable { return jsonWriter.toString(); } - /** - * 将JSON内容写入Writer
- * Warning: This method assumes that the data structure is acyclical. - * - * @param writer writer - * @throws JSONException JSON相关异常 - */ - void write(JSONWriter writer) throws JSONException; - /** * 转为实体类对象 * diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/JSONArray.java b/hutool-json/src/main/java/org/dromara/hutool/json/JSONArray.java index 46cabb2e2..77ce2f478 100644 --- a/hutool-json/src/main/java/org/dromara/hutool/json/JSONArray.java +++ b/hutool-json/src/main/java/org/dromara/hutool/json/JSONArray.java @@ -120,7 +120,7 @@ public class JSONArray extends ListWrapper implements JSON, JSONGetter implements JSON, JSONGetter implements JSON, JSONGe */ public JSONObject putAllObj(final Map map) { if(MapUtil.isNotEmpty(map)){ - for (final Entry entry : map.entrySet()) { - this.putObj(StrUtil.toStringOrNull(entry.getKey()), entry.getValue()); - } + map.forEach((key, value) -> putObj(StrUtil.toStringOrNull(key), value)); } return this; } @@ -235,7 +233,7 @@ public class JSONObject extends MapWrapper implements JSON, JSONGe * @throws JSONException 值是无穷数字抛出此异常 */ public JSONObject putObj(final String key, final Object value) throws JSONException { - this.put(key, factory.getMapper().map(value)); + this.put(key, factory.getMapper().toJSON(value)); return this; } diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/serializer/JSONMapper.java b/hutool-json/src/main/java/org/dromara/hutool/json/serializer/JSONMapper.java index 68b727d02..8f24d9be3 100644 --- a/hutool-json/src/main/java/org/dromara/hutool/json/serializer/JSONMapper.java +++ b/hutool-json/src/main/java/org/dromara/hutool/json/serializer/JSONMapper.java @@ -18,23 +18,18 @@ package org.dromara.hutool.json.serializer; import org.dromara.hutool.core.lang.Opt; import org.dromara.hutool.core.reflect.TypeReference; -import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.util.ObjUtil; import org.dromara.hutool.json.*; -import org.dromara.hutool.json.reader.JSONTokener; import org.dromara.hutool.json.serializer.impl.DefaultDeserializer; -import org.dromara.hutool.json.xml.JSONXMLParser; -import org.dromara.hutool.json.xml.ParseConfig; import java.io.Serializable; import java.lang.reflect.Type; -import java.util.Map; import java.util.Optional; /** * 对象和JSON值映射器,用于Java对象和JSON对象互转
*
    - *
  • Java对象转JSON:{@link #map(Object)}
  • + *
  • Java对象转JSON:{@link #toJSON(Object)}
  • *
  • JSON转Java对象:{@link #toBean(JSON, Type)}
  • *
*

@@ -70,6 +65,8 @@ public class JSONMapper implements Serializable { this.factory = factory; } + // region ----- typeAdapterManager + /** * 获取自定义类型转换器,用于将自定义类型转换为JSONObject * @@ -114,6 +111,7 @@ public class JSONMapper implements Serializable { initTypeAdapterManager().register(typeAdapter); return this; } + //endregion /** * 转为实体类对象 @@ -129,68 +127,18 @@ public class JSONMapper implements Serializable { type = ((TypeReference) type).getType(); } - JSONDeserializer deserializer = null; - // 自定义反序列化 - if (null != this.typeAdapterManager) { - deserializer = this.typeAdapterManager.getDeserializer(json, type); - } - // 全局自定义反序列化 - if (null == deserializer) { - deserializer = TypeAdapterManager.getInstance().getDeserializer(json, type); - } - final boolean ignoreError = ObjUtil.defaultIfNull(this.factory.getConfig(), JSONConfig::isIgnoreError, false); - if (null == deserializer) { - deserializer = DefaultDeserializer.INSTANCE; - } - + final JSONDeserializer deserializer = getDeserializer(json, type); try { return (T) deserializer.deserialize(json, type); } catch (final Exception e) { - if (ignoreError) { + if (ObjUtil.defaultIfNull(this.factory.getConfig(), JSONConfig::isIgnoreError, false)) { return null; } throw e; } } - /** - * 将JSONObject转换为JSONArrayM
- * 在普通的Serializer中,JSONObject会被直接返回,如果想转为JSONArray, - * - * @param jsonObject JSONObject - * @return JSONArray - */ - public JSONArray mapFromJSONObject(final JSONObject jsonObject) { - final JSONArray array = factory.ofArray(); - for (final Map.Entry entry : jsonObject) { - array.addObj(entry); - } - return array; - } - - /** - * 解析JSON字符串或XML字符串为JSON结构
- * 在普通的Serializer中,字符串会被作为普通字符串转为{@link JSONPrimitive},此处做区分 - * - * @param source JSON字符串或XML字符串 - * @return JSON对象 - */ - public JSON map(final CharSequence source) { - final String jsonStr = StrUtil.trim(source); - if (StrUtil.isEmpty(jsonStr)) { - // https://www.rfc-editor.org/rfc/rfc8259#section-7 - // 未被包装的空串理解为null - return null; - } - if (StrUtil.startWith(jsonStr, '<')) { - // 可能为XML - final JSONObject jsonObject = this.factory.ofObj(); - JSONXMLParser.of(ParseConfig.of(), this.factory.getPredicate()).parseJSONObject(jsonStr, jsonObject); - return jsonObject; - } - - return mapFromTokener(new JSONTokener(source)); - } + // region ----- toJSON /** * 在需要的时候转换映射对象
@@ -201,12 +149,11 @@ public class JSONMapper implements Serializable { *
  • standard property (Double, String, et al) =》 原对象
  • *
  • 其它 =》 尝试包装为JSONObject,否则返回{@code null}
  • * - * 注意,此方法不支持JSON字符串的解析,解析请用{@link #map(CharSequence)} * * @param obj 被映射的对象 * @return 映射后的值,null表示此值需被忽略 */ - public JSON map(final Object obj) { + public JSON toJSON(final Object obj) { return mapTo(obj, null); } @@ -221,7 +168,7 @@ public class JSONMapper implements Serializable { * @param obj 被映射的对象 * @return 映射后的值,null表示此值需被忽略 */ - public JSONObject mapObj(final Object obj) { + public JSONObject toJSONObject(final Object obj) { return mapTo(obj, factory.ofObj()); } @@ -235,9 +182,10 @@ public class JSONMapper implements Serializable { * @param obj 被映射的对象 * @return 映射后的值,null表示此值需被忽略 */ - public JSONArray mapArray(final Object obj) { + public JSONArray toJSONArray(final Object obj) { return mapTo(obj, factory.ofArray()); } + // endregion /** * 在需要的时候转换映射对象
    @@ -272,6 +220,15 @@ public class JSONMapper implements Serializable { } } + // JSONPrimitive对象 + // 考虑性能问题,默认原始类型对象直接包装为JSONPrimitive,不再查找TypeAdapter + // 如果原始类型想转为其他JSON类型,依旧可以查找TypeAdapter + if (JSONPrimitive.isTypeForJSONPrimitive(obj)) { + if (null == json || json instanceof JSONPrimitive) { + return (T) factory.ofPrimitive(obj); + } + } + // JSON对象如果与预期结果类型一致,则直接返回 if (obj instanceof JSON) { if (null != json) { @@ -283,16 +240,7 @@ public class JSONMapper implements Serializable { } } - final Class clazz = obj.getClass(); - JSONSerializer serializer = null; - // 自定义序列化 - if (null != this.typeAdapterManager) { - serializer = this.typeAdapterManager.getSerializer(obj, clazz); - } - // 全局自定义序列化 - if (null == serializer) { - serializer = TypeAdapterManager.getInstance().getSerializer(obj, clazz); - } + final JSONSerializer serializer = getSerializer(obj, obj.getClass()); final boolean ignoreError = ObjUtil.defaultIfNull(this.factory.getConfig(), JSONConfig::isIgnoreError, false); if (null == serializer) { if (ignoreError) { @@ -322,16 +270,6 @@ public class JSONMapper implements Serializable { json.getClass().getName(), result.getClass().getName()); } - /** - * 从{@link JSONTokener} 中读取JSON字符串,并转换为JSON - * - * @param tokener {@link JSONTokener} - * @return JSON - */ - private JSON mapFromTokener(final JSONTokener tokener) { - return this.factory.ofParser(tokener).parse(); - } - /** * 初始化类型转换器管理器,如果尚未初始化,则初始化,否则直接返回 * @@ -347,4 +285,48 @@ public class JSONMapper implements Serializable { } return this.typeAdapterManager; } + + /** + * 获取JSON对象对应的序列化器,先查找局部自定义,如果没有则查找全局自定义 + * + * @param obj 对象 + * @param clazz 对象类型 + * @return {@link JSONSerializer} + */ + private JSONSerializer getSerializer(final Object obj, final Class clazz) { + JSONSerializer serializer = null; + // 自定义序列化 + if (null != this.typeAdapterManager) { + serializer = this.typeAdapterManager.getSerializer(obj, clazz); + } + // 全局自定义序列化 + if (null == serializer) { + serializer = TypeAdapterManager.getInstance().getSerializer(obj, clazz); + } + return serializer; + } + + /** + * 获取JSON对象对应的反序列化器,先查找局部自定义,如果没有则查找全局自定义,如果都没有则使用默认反序列化器 + * + * @param json JSON对象 + * @param type 反序列化目标类型 + * @return {@link JSONDeserializer} + */ + private JSONDeserializer getDeserializer(final JSON json, final Type type) { + JSONDeserializer deserializer = null; + // 自定义反序列化 + if (null != this.typeAdapterManager) { + deserializer = this.typeAdapterManager.getDeserializer(json, type); + } + // 全局自定义反序列化 + if (null == deserializer) { + deserializer = TypeAdapterManager.getInstance().getDeserializer(json, type); + } + // 默认反序列化 + if (null == deserializer) { + deserializer = DefaultDeserializer.INSTANCE; + } + return deserializer; + } } diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/serializer/TypeAdapterManager.java b/hutool-json/src/main/java/org/dromara/hutool/json/serializer/TypeAdapterManager.java index 646e9d3cc..7b19a4f69 100644 --- a/hutool-json/src/main/java/org/dromara/hutool/json/serializer/TypeAdapterManager.java +++ b/hutool-json/src/main/java/org/dromara/hutool/json/serializer/TypeAdapterManager.java @@ -290,6 +290,7 @@ public class TypeAdapterManager { manager.register(ResourceBundleSerializer.INSTANCE); // 自定义反序列化器 + manager.register(JSONPrimitiveDeserializer.INSTANCE); manager.register(KBeanDeserializer.INSTANCE); manager.register(RecordDeserializer.INSTANCE); manager.register(Triple.class, TripleDeserializer.INSTANCE); @@ -297,7 +298,6 @@ public class TypeAdapterManager { manager.register(Tuple.class, TupleDeserializer.INSTANCE); // 自定义类型适配器 - manager.register(JSONPrimitiveTypeAdapter.INSTANCE); manager.register(CharSequenceTypeAdapter.INSTANCE); manager.register(DateTypeAdapter.INSTANCE); manager.register(CalendarTypeAdapter.INSTANCE); diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/serializer/impl/CharSequenceTypeAdapter.java b/hutool-json/src/main/java/org/dromara/hutool/json/serializer/impl/CharSequenceTypeAdapter.java index 9c2912ea7..388954958 100644 --- a/hutool-json/src/main/java/org/dromara/hutool/json/serializer/impl/CharSequenceTypeAdapter.java +++ b/hutool-json/src/main/java/org/dromara/hutool/json/serializer/impl/CharSequenceTypeAdapter.java @@ -19,6 +19,7 @@ package org.dromara.hutool.json.serializer.impl; import org.dromara.hutool.core.reflect.TypeUtil; import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.json.JSON; +import org.dromara.hutool.json.JSONFactory; import org.dromara.hutool.json.JSONObject; import org.dromara.hutool.json.JSONPrimitive; import org.dromara.hutool.json.reader.JSONTokener; @@ -31,7 +32,13 @@ import org.dromara.hutool.json.xml.ParseConfig; import java.lang.reflect.Type; /** - * CharSequence类型适配器,用于处理未匹配的JSON类型。 + * {@link CharSequence}类型适配器,主要用于: + *
      + *
    • 序列化(serialize):按照给定类型,解析JSON或XML字符串为{@link JSON}
    • + *
    • 反序列化(deserialize):如果为原始值,返回原始值并调用toString方法,其他JSON对象直接转为JSON字符换。
    • + *
    + * + * {@link CharSequence}适配器主要解决在JSON的get调用时,如果用户指定为字符串类型转换问题。 * * @author looly * @since 6.0.0 @@ -55,7 +62,22 @@ public class CharSequenceTypeAdapter implements MatcherJSONSerializer, MatcherJSONDeserializer { +public class JSONPrimitiveDeserializer implements MatcherJSONDeserializer { /** * 单例 */ - public static final JSONPrimitiveTypeAdapter INSTANCE = new JSONPrimitiveTypeAdapter(); - - @Override - public boolean match(final Object bean, final JSONContext context) { - return JSONPrimitive.isTypeForJSONPrimitive(bean); - } + public static final JSONPrimitiveDeserializer INSTANCE = new JSONPrimitiveDeserializer(); @Override public boolean match(final JSON json, final Type deserializeType) { return json instanceof JSONPrimitive && JSONPrimitive.isTypeForJSONPrimitive(TypeUtil.getClass(deserializeType)); } - @Override - public JSON serialize(Object bean, final JSONContext context) { - if(bean instanceof Character){ - // 字符按照字符串存储 - bean = bean.toString(); - } - - return context.getOrCreatePrimitive(bean); - } - @Override public Object deserialize(final JSON json, final Type deserializeType) { final Object value = json.asJSONPrimitive().getValue(); diff --git a/hutool-json/src/test/java/org/dromara/hutool/json/jmh/JsonPutJmh.java b/hutool-json/src/test/java/org/dromara/hutool/json/jmh/JsonPutJmh.java index 8b0fad48e..7641930f5 100644 --- a/hutool-json/src/test/java/org/dromara/hutool/json/jmh/JsonPutJmh.java +++ b/hutool-json/src/test/java/org/dromara/hutool/json/jmh/JsonPutJmh.java @@ -46,11 +46,11 @@ public class JsonPutJmh { @Benchmark public void hutoolJmh() { - testData.forEach(hutoolJSON::putObj); + hutoolJSON.putAllObj(testData); } @Benchmark public void fastJSONJmh() { - testData.forEach(fastJSON::put); + fastJSON.putAll(testData); } }