From 6d1f500bb2d60ab4c94c568b8580800ed57e6b42 Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 11 Oct 2024 22:05:39 +0800 Subject: [PATCH] fix code --- .../org/dromara/hutool/json/JSONObject.java | 45 ++++++++++++------ .../json/serializer/impl/MapTypeAdapter.java | 30 ++++++++---- .../hutool/json/issues/IssueIAWE3HTest.java | 46 +++++++++++++++++++ 3 files changed, 99 insertions(+), 22 deletions(-) create mode 100644 hutool-json/src/test/java/org/dromara/hutool/json/issues/IssueIAWE3HTest.java diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/JSONObject.java b/hutool-json/src/main/java/org/dromara/hutool/json/JSONObject.java index 7f4277e0e..7e2a155f6 100644 --- a/hutool-json/src/main/java/org/dromara/hutool/json/JSONObject.java +++ b/hutool-json/src/main/java/org/dromara/hutool/json/JSONObject.java @@ -23,6 +23,7 @@ import org.dromara.hutool.core.func.SerSupplier; import org.dromara.hutool.core.lang.mutable.MutableEntry; import org.dromara.hutool.core.map.MapUtil; import org.dromara.hutool.core.map.MapWrapper; +import org.dromara.hutool.core.reflect.TypeUtil; import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.util.ObjUtil; import org.dromara.hutool.json.support.InternalJSONUtil; @@ -41,7 +42,7 @@ import java.util.Map; * * @author looly */ -public class JSONObject extends MapWrapper implements JSON, JSONGetter{ +public class JSONObject extends MapWrapper implements JSON, JSONGetter { private static final long serialVersionUID = 1L; /** @@ -52,6 +53,7 @@ public class JSONObject extends MapWrapper implements JSON, JSONGe private final JSONFactory factory; // region ----- 构造 + /** * 构造,初始容量为 {@link #DEFAULT_CAPACITY},KEY有序 */ @@ -113,6 +115,7 @@ public class JSONObject extends MapWrapper implements JSON, JSONGe } // region ----- get + /** * 根据lambda的方法引用,获取 * @@ -130,9 +133,9 @@ public class JSONObject extends MapWrapper implements JSON, JSONGe public Object getObj(final String key, final Object defaultValue) { final Object value; final JSON json = get(key); - if(json instanceof JSONPrimitive){ + if (json instanceof JSONPrimitive) { value = ((JSONPrimitive) json).getValue(); - }else { + } else { value = json; } return ObjUtil.defaultIfNull(value, defaultValue); @@ -145,6 +148,7 @@ public class JSONObject extends MapWrapper implements JSON, JSONGe // endregion // region ----- increment or append + /** * 对值加一,如果值不存在,赋值1,如果为数字类型,做加一操作 * @@ -154,13 +158,13 @@ public class JSONObject extends MapWrapper implements JSON, JSONGe */ public JSONObject increment(final String key) throws JSONException { final JSON json = this.get(key); - if(null == json){ + if (null == json) { return putValue(key, 1); } - if(json instanceof JSONPrimitive){ + if (json instanceof JSONPrimitive) { final JSONPrimitive jsonPrimitive = (JSONPrimitive) json; - if(jsonPrimitive.isNumber()){ + if (jsonPrimitive.isNumber()) { jsonPrimitive.increment(); return this; } @@ -177,8 +181,8 @@ public class JSONObject extends MapWrapper implements JSON, JSONGe *
  • 如果值是一个其他值,则和旧值共同组合为一个{@link JSONArray}
  • * * - * @param key 键 - * @param value 值 + * @param key 键 + * @param value 值 * @return this. * @throws JSONException 如果给定键为{@code null}或者键对应的值存在且为非JSONArray * @since 6.0.0 @@ -197,6 +201,7 @@ public class JSONObject extends MapWrapper implements JSON, JSONGe // endregion // region ----- put + /** * 通过lambda批量设置值
    * 实际使用时,可以使用getXXX的方法引用来完成键值对的赋值: @@ -221,7 +226,7 @@ public class JSONObject extends MapWrapper implements JSON, JSONGe * @throws JSONException 值是无穷数字抛出此异常 */ public JSONObject putAllValue(final Map map) { - if(MapUtil.isNotEmpty(map)){ + if (MapUtil.isNotEmpty(map)) { map.forEach((key, value) -> putValue(StrUtil.toStringOrNull(key), value)); } return this; @@ -233,7 +238,7 @@ public class JSONObject extends MapWrapper implements JSON, JSONGe * @param key 键 * @return this. */ - public JSONObject putNull(final String key){ + public JSONObject putNull(final String key) { this.put(key, null); return this; } @@ -300,7 +305,7 @@ public class JSONObject extends MapWrapper implements JSON, JSONGe * @throws JSONException 值是无穷数字抛出此异常 */ public JSONObject putValue(final String key, final Object value) throws JSONException { - if(null == value){ + if (null == value) { return putNull(key); } // put时,如果value为字符串,不解析,而是作为JSONPrimitive对待 @@ -311,8 +316,8 @@ public class JSONObject extends MapWrapper implements JSON, JSONGe /** * 设置键值对到JSONObject中,在忽略null模式下,如果值为{@code null},将此键移除 * - * @param key 键 - * @param value 值对象. 可以是以下类型: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or the JSONNull.NULL. + * @param key 键 + * @param value 值对象. 可以是以下类型: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or the JSONNull.NULL. * @return 旧值 * @throws JSONException 值是无穷数字抛出此异常 */ @@ -330,7 +335,7 @@ public class JSONObject extends MapWrapper implements JSON, JSONGe final JSONConfig.DuplicateMode duplicateMode = config.getDuplicateMode(); if (JSONConfig.DuplicateMode.OVERRIDE != duplicateMode && containsKey(key)) { - if(JSONConfig.DuplicateMode.IGNORE == duplicateMode){ + if (JSONConfig.DuplicateMode.IGNORE == duplicateMode) { return null; } throw new JSONException("Duplicate key \"{}\"", key); @@ -339,6 +344,18 @@ public class JSONObject extends MapWrapper implements JSON, JSONGe } // endregion + /** + * 将JSONObject转换为指定类型的Map + * + * @param keyType 键类型Class + * @param valueType 值类型Class + * @param 键类型 + * @param 值类型 + * @return Map + */ + public Map toMap(final Class keyType, final Class valueType) { + return toBean(TypeUtil.createParameterizedType(Map.class, keyType, valueType)); + } @Override public String toString() { diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/serializer/impl/MapTypeAdapter.java b/hutool-json/src/main/java/org/dromara/hutool/json/serializer/impl/MapTypeAdapter.java index 8c99adbd1..bf801dca9 100644 --- a/hutool-json/src/main/java/org/dromara/hutool/json/serializer/impl/MapTypeAdapter.java +++ b/hutool-json/src/main/java/org/dromara/hutool/json/serializer/impl/MapTypeAdapter.java @@ -53,7 +53,7 @@ public class MapTypeAdapter implements MatcherJSONSerializer>, Matcher @Override public boolean match(final JSON json, final Type deserializeType) { - if(json instanceof JSONObject){ + if (json instanceof JSONObject) { final Class rawType = TypeUtil.getClass(deserializeType); return Map.class.isAssignableFrom(rawType); } @@ -65,13 +65,13 @@ public class MapTypeAdapter implements MatcherJSONSerializer>, Matcher final JSON contextJson = context.getContextJson(); // 序列化为JSONArray - if(contextJson instanceof JSONArray){ + if (contextJson instanceof JSONArray) { final Iterator iter; - if(bean instanceof Iterator){ + if (bean instanceof Iterator) { iter = (Iterator) bean; - } else if(bean instanceof Iterable){ + } else if (bean instanceof Iterable) { iter = ((Iterable) bean).iterator(); - } else{ + } else { iter = bean.entrySet().iterator(); } IterTypeAdapter.mapFromIterator(bean, iter, (JSONArray) contextJson); @@ -87,18 +87,32 @@ public class MapTypeAdapter implements MatcherJSONSerializer>, Matcher return result; } - @SuppressWarnings({"unchecked", "rawtypes"}) @Override public Map deserialize(final JSON json, final Type deserializeType) { - final Map map = MapUtil.createMap(TypeUtil.getClass(deserializeType), LinkedHashMap::new); final Type keyType = TypeUtil.getTypeArgument(deserializeType, 0); final Type valueType = TypeUtil.getTypeArgument(deserializeType, 1); + return toMap(json, + TypeUtil.getClass(deserializeType), + keyType, + valueType); + } + /** + * 将JSON对象转换为Map + * + * @param json JSON对象 + * @param mapClass Map类型 + * @param keyType 键类型 + * @param valueType 值类型 + * @return Map + */ + public Map toMap(final JSON json, final Class mapClass, final Type keyType, final Type valueType) { + final Map map = MapUtil.createMap(mapClass, LinkedHashMap::new); for (final Map.Entry entry : (JSONObject) json) { map.put( // key类型为String转目标类型,使用标准转换器 ConvertUtil.convert(keyType, entry.getKey()), - ObjUtil.apply(entry.getValue(), (value)-> value.toBean(valueType)) + ObjUtil.apply(entry.getValue(), (value) -> value.toBean(valueType)) ); } return map; diff --git a/hutool-json/src/test/java/org/dromara/hutool/json/issues/IssueIAWE3HTest.java b/hutool-json/src/test/java/org/dromara/hutool/json/issues/IssueIAWE3HTest.java new file mode 100644 index 000000000..9b8fa9d3f --- /dev/null +++ b/hutool-json/src/test/java/org/dromara/hutool/json/issues/IssueIAWE3HTest.java @@ -0,0 +1,46 @@ +/* + * 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.issues; + +import org.dromara.hutool.core.reflect.TypeReference; +import org.dromara.hutool.json.JSONObject; +import org.dromara.hutool.json.JSONUtil; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.Map; + +public class IssueIAWE3HTest { + @Test + void toMapTest() { + final String jsonStr = "{\n" + + " \"reply\": \"hi\",\n" + + " \"solved\": true,\n" + + " \"notifyTypes\": [\n" + + " \"push\"\n" + + " ]\n" + + "}"; + + final JSONObject jsonObject = JSONUtil.parseObj(jsonStr); + + final Map map = jsonObject.toBean(new TypeReference>() {}); + Assertions.assertEquals("hi", map.get("reply")); + + final Map map2 = jsonObject.toMap(String.class, Object.class); + Assertions.assertEquals("hi", map2.get("reply")); + } +}