From 63028906b9bfe4f448f92044044b86762feadfb7 Mon Sep 17 00:00:00 2001 From: Looly Date: Thu, 8 Sep 2022 02:21:05 +0800 Subject: [PATCH] add converter for json --- .../core/convert/RegisterConverter.java | 39 +++++++++---------- .../core/convert/impl/MapConverter.java | 2 +- .../main/java/cn/hutool/json/JSONConfig.java | 7 ++++ .../cn/hutool/json/convert/JSONConverter.java | 12 ++++++ .../{ => cn/hutool/json}/Issue2555Test.java | 2 + 5 files changed, 41 insertions(+), 21 deletions(-) rename hutool-json/src/test/java/{ => cn/hutool/json}/Issue2555Test.java (98%) mode change 100755 => 100644 diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/RegisterConverter.java b/hutool-core/src/main/java/cn/hutool/core/convert/RegisterConverter.java index d1426bc9e..7ff40594a 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/RegisterConverter.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/RegisterConverter.java @@ -29,9 +29,6 @@ import cn.hutool.core.convert.impl.XMLGregorianCalendarConverter; import cn.hutool.core.convert.impl.ZoneIdConverter; import cn.hutool.core.date.DateTime; import cn.hutool.core.lang.Opt; -import cn.hutool.core.reflect.ClassUtil; -import cn.hutool.core.reflect.TypeUtil; -import cn.hutool.core.util.ServiceLoaderUtil; import javax.xml.datatype.XMLGregorianCalendar; import java.io.Serializable; @@ -78,6 +75,25 @@ import java.util.concurrent.atomic.AtomicReference; public class RegisterConverter implements Converter, Serializable { private static final long serialVersionUID = 1L; + /** + * 类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例 没有绑定关系,而且只有被调用到才会装载,从而实现了延迟加载 + */ + private static class SingletonHolder { + /** + * 静态初始化器,由JVM来保证线程安全 + */ + private static final CompositeConverter INSTANCE = new CompositeConverter(); + } + + /** + * 获得单例的 ConverterRegistry + * + * @return ConverterRegistry + */ + public static CompositeConverter getInstance() { + return RegisterConverter.SingletonHolder.INSTANCE; + } + /** * 默认类型转换器 */ @@ -92,7 +108,6 @@ public class RegisterConverter implements Converter, Serializable { */ public RegisterConverter() { registerDefault(); - registerCustomBySpi(); } @Override @@ -233,20 +248,4 @@ public class RegisterConverter implements Converter, Serializable { defaultConverterMap.put(Optional.class, new OptionalConverter());// since 5.0.0 defaultConverterMap.put(Opt.class, new OptConverter());// since 5.7.16 } - - /** - * 使用SPI加载转换器 - */ - private void registerCustomBySpi() { - ServiceLoaderUtil.load(Converter.class).forEach(converter -> { - try { - final Type type = TypeUtil.getTypeArgument(ClassUtil.getClass(converter)); - if (null != type) { - putCustom(type, converter); - } - } catch (final Exception ignore) { - // 忽略注册失败的 - } - }); - } } diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/impl/MapConverter.java b/hutool-core/src/main/java/cn/hutool/core/convert/impl/MapConverter.java index e1d733cdf..8a4eb3d4f 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/impl/MapConverter.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/impl/MapConverter.java @@ -67,7 +67,7 @@ public class MapConverter implements Converter, Serializable { // 二次转换,转换键值类型 map = convert(targetType, keyType, valueType, map); } else { - throw new UnsupportedOperationException(StrUtil.format("Unsupport toMap value type: {}", value.getClass().getName())); + throw new UnsupportedOperationException(StrUtil.format("Unsupported toMap value type: {}", value.getClass().getName())); } return map; } diff --git a/hutool-json/src/main/java/cn/hutool/json/JSONConfig.java b/hutool-json/src/main/java/cn/hutool/json/JSONConfig.java index bb2a36c5d..8a01af8ab 100755 --- a/hutool-json/src/main/java/cn/hutool/json/JSONConfig.java +++ b/hutool-json/src/main/java/cn/hutool/json/JSONConfig.java @@ -7,6 +7,7 @@ import cn.hutool.core.convert.impl.DateConverter; import cn.hutool.core.convert.impl.TemporalAccessorConverter; import cn.hutool.core.reflect.TypeUtil; import cn.hutool.core.text.StrUtil; +import cn.hutool.json.convert.JSONConverter; import java.io.Serializable; import java.time.temporal.TemporalAccessor; @@ -59,6 +60,12 @@ public class JSONConfig implements Serializable { */ private Converter converter = (type, value)->{ final Class rawType = TypeUtil.getClass(type); + if(null == rawType){ + return value; + } + if(JSON.class.isAssignableFrom(rawType)){ + return JSONConverter.INSTANCE.toJSON(value); + } if(Date.class.isAssignableFrom(rawType) || TemporalAccessor.class.isAssignableFrom(rawType)){ // 用户指定了日期格式,获取日期属性时使用对应格式 final String valueStr = Convert.convertWithCheck(String.class, value, null, isIgnoreError()); diff --git a/hutool-json/src/main/java/cn/hutool/json/convert/JSONConverter.java b/hutool-json/src/main/java/cn/hutool/json/convert/JSONConverter.java index 03e078204..96748a5f9 100644 --- a/hutool-json/src/main/java/cn/hutool/json/convert/JSONConverter.java +++ b/hutool-json/src/main/java/cn/hutool/json/convert/JSONConverter.java @@ -4,6 +4,7 @@ import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.copier.BeanCopier; import cn.hutool.core.convert.ConvertException; import cn.hutool.core.convert.Converter; +import cn.hutool.core.convert.RegisterConverter; import cn.hutool.core.convert.impl.ArrayConverter; import cn.hutool.core.convert.impl.CollectionConverter; import cn.hutool.core.convert.impl.MapConverter; @@ -42,6 +43,11 @@ import java.util.Map; public class JSONConverter implements Converter { public static final JSONConverter INSTANCE = new JSONConverter(null); + static { + RegisterConverter.getInstance().putCustom(JSONObject.class, INSTANCE); + RegisterConverter.getInstance().putCustom(JSONArray.class, INSTANCE); + } + /** * 创建JSON转换器 * @@ -141,6 +147,12 @@ public class JSONConverter implements Converter { return result; } + // 标准转换器 + final Converter converter = RegisterConverter.getInstance().getConverter(targetType, true); + if (null != converter) { + return (T) converter.convert(targetType, json); + } + // 尝试转Bean if (BeanUtil.isBean(rawType)) { return BeanCopier.of(json, diff --git a/hutool-json/src/test/java/Issue2555Test.java b/hutool-json/src/test/java/cn/hutool/json/Issue2555Test.java old mode 100755 new mode 100644 similarity index 98% rename from hutool-json/src/test/java/Issue2555Test.java rename to hutool-json/src/test/java/cn/hutool/json/Issue2555Test.java index d62c63bb5..c020737b9 --- a/hutool-json/src/test/java/Issue2555Test.java +++ b/hutool-json/src/test/java/cn/hutool/json/Issue2555Test.java @@ -1,3 +1,5 @@ +package cn.hutool.json; + import cn.hutool.json.JSON; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil;