diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/serializer/SerializerManager.java b/hutool-json/src/main/java/org/dromara/hutool/json/serializer/SerializerManager.java index 669f25b25..2d2b5398f 100644 --- a/hutool-json/src/main/java/org/dromara/hutool/json/serializer/SerializerManager.java +++ b/hutool-json/src/main/java/org/dromara/hutool/json/serializer/SerializerManager.java @@ -312,7 +312,9 @@ public class SerializerManager { // issue#I5WDP0 对于Kotlin对象,由于参数可能非空限制,导致无法创建一个默认的对象再赋值 manager.register(KBeanDeserializer.INSTANCE); + manager.register(CollectionDeserializer.INSTANCE); + manager.register(ArrayDeserializer.INSTANCE); manager.register(MapDeserializer.INSTANCE); manager.register(EntryDeserializer.INSTANCE); manager.register(RecordDeserializer.INSTANCE); diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/serializer/impl/ArrayDeserializer.java b/hutool-json/src/main/java/org/dromara/hutool/json/serializer/impl/ArrayDeserializer.java new file mode 100644 index 000000000..94a8292eb --- /dev/null +++ b/hutool-json/src/main/java/org/dromara/hutool/json/serializer/impl/ArrayDeserializer.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2024 Hutool Team and hutool.cn + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.dromara.hutool.json.serializer.impl; + +import org.dromara.hutool.core.reflect.TypeUtil; +import org.dromara.hutool.json.JSON; +import org.dromara.hutool.json.JSONArray; +import org.dromara.hutool.json.JSONObject; +import org.dromara.hutool.json.serializer.MatcherJSONDeserializer; + +import java.lang.reflect.Array; +import java.lang.reflect.Type; +import java.util.Map; + +/** + * Map.Entry反序列化器,用于将JSON对象转换为Map.Entry对象。 + * + * @author looly + * @since 6.0.0 + */ +public class ArrayDeserializer implements MatcherJSONDeserializer { + + /** + * 单例 + */ + public static final ArrayDeserializer INSTANCE = new ArrayDeserializer(); + + @Override + public boolean match(final JSON json, final Type deserializeType) { + if (json instanceof JSONArray || json instanceof JSONObject) { + return TypeUtil.getClass(deserializeType).isArray(); + } + return false; + } + + @Override + public Object deserialize(final JSON json, final Type deserializeType) { + final int size = json.size(); + final Class componentType = TypeUtil.getClass(deserializeType).getComponentType(); + final Object result = Array.newInstance(componentType, size); + if (json instanceof JSONObject) { + fill((JSONObject) json, result, componentType); + } else { + fill((JSONArray) json, result, componentType); + } + return result; + } + + /** + * 将JSONObject填充到数组 + * + * @param json JSONObject + * @param result 结果集合 + * @param componentType 元素类型 + */ + private void fill(final JSONObject json, final Object result, final Type componentType) { + int i = 0; + for (final Map.Entry entry : json) { + Array.set(result, i, entry.getValue().toBean(componentType)); + i++; + } + } + + /** + * 将JSONObject填充到数组 + * + * @param json JSONObject + * @param result 结果集合 + * @param componentType 元素类型 + */ + private void fill(final JSONArray json, final Object result, final Type componentType) { + int i = 0; + for (final JSON element : json) { + Array.set(result, i, element.toBean(componentType)); + i++; + } + } +} diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/serializer/impl/CollectionDeserializer.java b/hutool-json/src/main/java/org/dromara/hutool/json/serializer/impl/CollectionDeserializer.java index 2a6d58141..a7395a42c 100644 --- a/hutool-json/src/main/java/org/dromara/hutool/json/serializer/impl/CollectionDeserializer.java +++ b/hutool-json/src/main/java/org/dromara/hutool/json/serializer/impl/CollectionDeserializer.java @@ -42,7 +42,7 @@ public class CollectionDeserializer implements MatcherJSONDeserializer rawType = TypeUtil.getClass(deserializeType); return Collection.class.isAssignableFrom(rawType); } @@ -51,44 +51,43 @@ public class CollectionDeserializer implements MatcherJSONDeserializer deserialize(final JSON json, final Type deserializeType) { + final Class rawType = TypeUtil.getClass(deserializeType); + final Type elementType = TypeUtil.getTypeArgument(deserializeType); + final Collection result = CollUtil.create(rawType, TypeUtil.getClass(elementType)); + + if (json instanceof JSONObject) { - return toCollection((JSONObject) json, deserializeType, TypeUtil.getClass(deserializeType)); + fill((JSONObject) json, result, elementType); + } else { + fill((JSONArray) json, result, elementType); } - return toCollection((JSONArray) json, deserializeType, TypeUtil.getClass(deserializeType)); + return result; } /** * 将JSONObject转换为集合 * - * @param json JSONObject - * @param deserializeType 反序列化类型 - * @param rawType 集合类型 - * @return 集合 + * @param json JSONObject + * @param result 结果集合 + * @param elementType 元素类型 */ - private Collection toCollection(final JSONObject json, final Type deserializeType, final Class rawType) { - final Type elementType = TypeUtil.getTypeArgument(deserializeType); - final Collection result = CollUtil.create(rawType, TypeUtil.getClass(elementType)); + private void fill(final JSONObject json, final Collection result, final Type elementType) { for (final Map.Entry entry : json) { result.add(entry.getValue().toBean(elementType)); } - return result; } /** * 将JSONArray转换为集合 * - * @param json JSONArray - * @param deserializeType 反序列化类型 - * @param rawType 集合类型 - * @return 集合 + * @param json JSONArray + * @param result 结果集合 + * @param elementType 元素类型 */ - private Collection toCollection(final JSONArray json, final Type deserializeType, final Class rawType) { - final Type elementType = TypeUtil.getTypeArgument(deserializeType); - final Collection result = CollUtil.create(rawType, TypeUtil.getClass(elementType)); + private void fill(final JSONArray json, final Collection result, final Type elementType) { for (final JSON element : json) { result.add(element.toBean(elementType)); } - return result; } } diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/serializer/impl/DefaultDeserializer.java b/hutool-json/src/main/java/org/dromara/hutool/json/serializer/impl/DefaultDeserializer.java index 71dfbca43..8c21e0323 100644 --- a/hutool-json/src/main/java/org/dromara/hutool/json/serializer/impl/DefaultDeserializer.java +++ b/hutool-json/src/main/java/org/dromara/hutool/json/serializer/impl/DefaultDeserializer.java @@ -16,9 +16,14 @@ package org.dromara.hutool.json.serializer.impl; +import org.dromara.hutool.core.bean.copier.ValueProviderToBeanCopier; +import org.dromara.hutool.core.convert.CompositeConverter; +import org.dromara.hutool.core.lang.copier.Copier; +import org.dromara.hutool.core.reflect.ConstructorUtil; import org.dromara.hutool.core.reflect.TypeUtil; import org.dromara.hutool.json.*; import org.dromara.hutool.json.serializer.JSONDeserializer; +import org.dromara.hutool.json.serializer.JSONObjectValueProvider; import java.lang.reflect.Type; @@ -33,7 +38,7 @@ public class DefaultDeserializer implements JSONDeserializer { public Object deserialize(final JSON json, final Type deserializeType) { // 当目标类型不确定时,返回原JSON final Class rawType = TypeUtil.getClass(deserializeType); - if (null == rawType || JSON.class.isAssignableFrom(rawType)) { + if (null == rawType || rawType == json.getClass()) { return json; } @@ -47,15 +52,51 @@ public class DefaultDeserializer implements JSONDeserializer { throw new JSONException("Unsupported JSON type: {}", json.getClass()); } + /** + * 从JSONObject反序列化 + * + * @param json JSONObject + * @param deserializeType 目标类型 + * @param rawType 目标类型 + * @return 反序列化后的对象 + */ private Object fromJSONObject(final JSONObject json, final Type deserializeType, final Class rawType) { - return json; + // 转为POJO + final Copier copier = new ValueProviderToBeanCopier<>( + new JSONObjectValueProvider(json), + ConstructorUtil.newInstanceIfPossible(rawType), + deserializeType, + InternalJSONUtil.toCopyOptions(json.config()) + ); + return copier.copy(); } + /** + * 从JSONArray反序列化 + * + * @param json JSONArray + * @param deserializeType 目标类型 + * @param rawType 目标类型 + * @return 反序列化后的对象 + */ private Object fromJSONArray(final JSONArray json, final Type deserializeType, final Class rawType) { return json; } + /** + * 从JSONPrimitive反序列化 + * + * @param json JSONPrimitive + * @param deserializeType 目标类型 + * @param rawType 目标类型 + * @return 反序列化后的对象 + */ private Object fromJSONPrimitive(final JSONPrimitive json, final Type deserializeType, final Class rawType) { - return json; + final Object value = json.getValue(); + if (null != value && rawType.isAssignableFrom(value.getClass())) { + return value; + } + + return CompositeConverter.getInstance().convert(deserializeType, value); } }