From 5622f5e7a7a8905b514e335f6a56161a7bf17182 Mon Sep 17 00:00:00 2001 From: TomShiDi <1341109792@qq.com> Date: Sun, 8 Dec 2024 15:41:43 +0800 Subject: [PATCH] =?UTF-8?q?feature:=20json=E7=9A=84getByPath=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E6=96=B0=E5=A2=9E=E6=9B=B4=E4=B8=BA=E9=80=9A=E7=94=A8?= =?UTF-8?q?=E7=9A=84=E6=8C=87=E5=AE=9A=E5=87=BA=E5=8F=82=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E9=87=8D=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/cn/hutool/json/JSON.java | 26 +++++++++++++++++++ .../main/java/cn/hutool/json/JSONArray.java | 9 ++++++- .../main/java/cn/hutool/json/JSONObject.java | 13 +++++++--- .../java/cn/hutool/json/JSONPathTest.java | 23 ++++++++++++++++ 4 files changed, 67 insertions(+), 4 deletions(-) diff --git a/hutool-json/src/main/java/cn/hutool/json/JSON.java b/hutool-json/src/main/java/cn/hutool/json/JSON.java index 4932f1e8a..9a5972cc9 100755 --- a/hutool-json/src/main/java/cn/hutool/json/JSON.java +++ b/hutool-json/src/main/java/cn/hutool/json/JSON.java @@ -97,6 +97,32 @@ public interface JSON extends Cloneable, Serializable, IJSONTypeConverter { */ T getByPath(String expression, Class resultType); + /** + * 通过表达式获取JSON中嵌套的对象
+ *
    + *
  1. .表达式,可以获取Bean对象中的属性(字段)值或者Map中key对应的值
  2. + *
  3. []表达式,可以获取集合等对象中对应index的值
  4. + *
+ *

+ * 表达式栗子: + * + *

+	 * persion
+	 * persion.name
+	 * persons[3]
+	 * person.friends[5].name
+	 * 
+ *

+ * 获取表达式对应值后转换为对应类型的值 + * + * @param expression 表达式 + * @param targetType 返回值类型 + * @return 对象 + * @see BeanPath#get(Object) + * @since 5.8.34 + */ + T getByPath(String expression, TypeReference targetType); + /** * 格式化打印JSON,缩进为4个空格 * diff --git a/hutool-json/src/main/java/cn/hutool/json/JSONArray.java b/hutool-json/src/main/java/cn/hutool/json/JSONArray.java index e7371f14f..636da5da7 100755 --- a/hutool-json/src/main/java/cn/hutool/json/JSONArray.java +++ b/hutool-json/src/main/java/cn/hutool/json/JSONArray.java @@ -3,6 +3,7 @@ package cn.hutool.json; import cn.hutool.core.bean.BeanPath; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Filter; +import cn.hutool.core.lang.TypeReference; import cn.hutool.core.lang.Validator; import cn.hutool.core.lang.mutable.Mutable; import cn.hutool.core.lang.mutable.MutableObj; @@ -13,6 +14,7 @@ import cn.hutool.json.serialize.JSONWriter; import java.io.StringWriter; import java.io.Writer; +import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; @@ -195,7 +197,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando */ public String join(String separator) throws JSONException { return StrJoiner.of(separator) - .append(this, InternalJSONUtil::valueToString).toString(); + .append(this, InternalJSONUtil::valueToString).toString(); } @Override @@ -218,6 +220,11 @@ public class JSONArray implements JSON, JSONGetter, List, Rando return JSONConverter.jsonConvert(resultType, getByPath(expression), getConfig()); } + @Override + public T getByPath(String expression, TypeReference targetType) { + return JSONConverter.jsonConvert(targetType, getByPath(expression), getConfig()); + } + @Override public void putByPath(String expression, Object value) { BeanPath.create(expression).set(this, value); diff --git a/hutool-json/src/main/java/cn/hutool/json/JSONObject.java b/hutool-json/src/main/java/cn/hutool/json/JSONObject.java index 327be1be0..d09a6b067 100755 --- a/hutool-json/src/main/java/cn/hutool/json/JSONObject.java +++ b/hutool-json/src/main/java/cn/hutool/json/JSONObject.java @@ -3,6 +3,7 @@ package cn.hutool.json; import cn.hutool.core.bean.BeanPath; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.lang.Filter; +import cn.hutool.core.lang.TypeReference; import cn.hutool.core.lang.mutable.MutablePair; import cn.hutool.core.map.CaseInsensitiveMap; import cn.hutool.core.map.MapUtil; @@ -14,6 +15,7 @@ import cn.hutool.json.serialize.JSONWriter; import java.io.StringWriter; import java.io.Writer; +import java.lang.reflect.Type; import java.math.BigDecimal; import java.math.BigInteger; import java.util.Collection; @@ -161,8 +163,8 @@ public class JSONObject extends MapWrapper implements JSON, JSON @Deprecated public JSONObject(Object source, boolean ignoreNullValue, boolean isOrder) { this(source, JSONConfig.create()// - .setIgnoreCase((source instanceof CaseInsensitiveMap))// - .setIgnoreNullValue(ignoreNullValue) + .setIgnoreCase((source instanceof CaseInsensitiveMap))// + .setIgnoreNullValue(ignoreNullValue) ); } @@ -320,6 +322,11 @@ public class JSONObject extends MapWrapper implements JSON, JSON return JSONConverter.jsonConvert(resultType, getByPath(expression), getConfig()); } + @Override + public T getByPath(String expression, TypeReference targetType) { + return JSONConverter.jsonConvert(targetType, getByPath(expression), getConfig()); + } + @Override public void putByPath(String expression, Object value) { BeanPath.create(expression).set(this, value); @@ -561,7 +568,7 @@ public class JSONObject extends MapWrapper implements JSON, JSON */ public Writer write(Writer writer, int indentFactor, int indent, Filter> filter) throws JSONException { final JSONWriter jsonWriter = JSONWriter.of(writer, indentFactor, indent, config) - .beginObj(); + .beginObj(); this.forEach((key, value) -> jsonWriter.writeField(new MutablePair<>(key, value), filter)); jsonWriter.end(); // 此处不关闭Writer,考虑writer后续还需要填内容 diff --git a/hutool-json/src/test/java/cn/hutool/json/JSONPathTest.java b/hutool-json/src/test/java/cn/hutool/json/JSONPathTest.java index 472def851..437f012cb 100644 --- a/hutool-json/src/test/java/cn/hutool/json/JSONPathTest.java +++ b/hutool-json/src/test/java/cn/hutool/json/JSONPathTest.java @@ -1,8 +1,12 @@ package cn.hutool.json; import static org.junit.jupiter.api.Assertions.*; + +import cn.hutool.core.lang.TypeReference; import org.junit.jupiter.api.Test; +import java.util.List; + /** * JSON路径单元测试 * @@ -27,4 +31,23 @@ public class JSONPathTest { Long accountId = JSONUtil.getByPath(json, "$.accountId", 0L); assertEquals(111L, accountId.longValue()); } + + @Test + public void getByPathTest3(){ + String str = "[{'accountId':1},{'accountId':2},{'accountId':3}]"; + JSON json = JSONUtil.parse(str); + // 返回指定泛型的对象 List + List accountIds = json.getByPath("$.accountId", new TypeReference>() { + }); + assertNotNull(accountIds); + assertArrayEquals(new Long[]{1L, 2L, 3L}, accountIds.toArray()); + + str = "{\"accountInfos\": [{\"accountId\":1},{\"accountId\":2},{\"accountId\":3}]}"; + json = JSONUtil.parse(str); + // 返回指定泛型的对象 List + accountIds = json.getByPath("$.accountInfos.accountId", new TypeReference>() { + }); + assertNotNull(accountIds); + assertArrayEquals(new Long[]{1L, 2L, 3L}, accountIds.toArray()); + } }