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 71cd5eda9..cff762d8e 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
@@ -29,7 +29,13 @@ import java.lang.reflect.Type;
import java.util.function.Predicate;
/**
- * JSON接口
+ * JSON树模型接口,表示树中的一个节点。实现包括:
+ *
+ * - {@link JSONObject}表示键值对形式的节点
+ * - {@link JSONArray}表示列表形式的节点
+ * - {@link JSONPrimitive}表示数字、Boolean、字符串形式的节点
+ * - {@code null}表示空节点
+ *
*
* @author Looly
*/
diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/convert/JSONConverter.java b/hutool-json/src/main/java/org/dromara/hutool/json/convert/JSONConverter.java
index 1e8dc9f9e..a4de6ec5f 100644
--- a/hutool-json/src/main/java/org/dromara/hutool/json/convert/JSONConverter.java
+++ b/hutool-json/src/main/java/org/dromara/hutool/json/convert/JSONConverter.java
@@ -30,7 +30,7 @@ import org.dromara.hutool.core.reflect.TypeUtil;
import org.dromara.hutool.core.reflect.kotlin.KClassUtil;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.json.*;
-import org.dromara.hutool.json.reader.JSONParser;
+import org.dromara.hutool.json.reader.OldJSONParser;
import org.dromara.hutool.json.reader.JSONTokener;
import org.dromara.hutool.json.serializer.*;
@@ -202,7 +202,7 @@ public class JSONConverter implements Converter, Serializable {
}
// RFC8259,JSON字符串值、number, boolean, or null
- final JSONParser jsonParser = JSONParser.of(new JSONTokener(jsonStr), config);
+ final OldJSONParser jsonParser = OldJSONParser.of(new JSONTokener(jsonStr), config);
final Object value = jsonParser.nextValue();
if (jsonParser.getTokener().nextClean() != JSONTokener.EOF) {
// 对于用户提供的未转义字符串导致解析未结束,报错
diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/mapper/JSONArrayMapper.java b/hutool-json/src/main/java/org/dromara/hutool/json/mapper/JSONArrayMapper.java
index 85421f271..300aaee4b 100644
--- a/hutool-json/src/main/java/org/dromara/hutool/json/mapper/JSONArrayMapper.java
+++ b/hutool-json/src/main/java/org/dromara/hutool/json/mapper/JSONArrayMapper.java
@@ -24,7 +24,7 @@ import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.json.JSONArray;
import org.dromara.hutool.json.JSONConfig;
import org.dromara.hutool.json.JSONException;
-import org.dromara.hutool.json.reader.JSONParser;
+import org.dromara.hutool.json.reader.OldJSONParser;
import org.dromara.hutool.json.reader.JSONTokener;
import org.dromara.hutool.json.serializer.JSONSerializer;
import org.dromara.hutool.json.serializer.SerializerManager;
@@ -98,8 +98,8 @@ public class JSONArrayMapper {
if (source instanceof JSONTokener) {
mapFromTokener((JSONTokener) source, JSONConfig.of(), jsonArray);
- }if (source instanceof JSONParser) {
- ((JSONParser)source).parseTo(jsonArray, this.predicate);
+ }if (source instanceof OldJSONParser) {
+ ((OldJSONParser)source).parseTo(jsonArray, this.predicate);
} else if (source instanceof CharSequence) {
// JSON字符串
mapFromStr((CharSequence) source, jsonArray);
@@ -164,6 +164,6 @@ public class JSONArrayMapper {
* @param jsonArray {@link JSONArray}
*/
private void mapFromTokener(final JSONTokener x, final JSONConfig config, final JSONArray jsonArray) {
- JSONParser.of(x, config).parseTo(jsonArray, this.predicate);
+ OldJSONParser.of(x, config).parseTo(jsonArray, this.predicate);
}
}
diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/mapper/JSONObjectMapper.java b/hutool-json/src/main/java/org/dromara/hutool/json/mapper/JSONObjectMapper.java
index 8733883f2..ad7e32146 100644
--- a/hutool-json/src/main/java/org/dromara/hutool/json/mapper/JSONObjectMapper.java
+++ b/hutool-json/src/main/java/org/dromara/hutool/json/mapper/JSONObjectMapper.java
@@ -25,7 +25,7 @@ import org.dromara.hutool.core.lang.mutable.MutableEntry;
import org.dromara.hutool.core.reflect.method.MethodUtil;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.json.*;
-import org.dromara.hutool.json.reader.JSONParser;
+import org.dromara.hutool.json.reader.OldJSONParser;
import org.dromara.hutool.json.reader.JSONTokener;
import org.dromara.hutool.json.serializer.JSONSerializer;
import org.dromara.hutool.json.serializer.SerializerManager;
@@ -111,9 +111,9 @@ public class JSONObjectMapper {
if (source instanceof JSONTokener) {
// JSONTokener
mapFromTokener((JSONTokener) source, jsonObject.config(), jsonObject);
- }if (source instanceof JSONParser) {
+ }if (source instanceof OldJSONParser) {
// JSONParser
- ((JSONParser) source).parseTo(jsonObject, this.predicate);
+ ((OldJSONParser) source).parseTo(jsonObject, this.predicate);
} else if (source instanceof Map) {
// Map
for (final Map.Entry, ?> e : ((Map, ?>) source).entrySet()) {
@@ -191,7 +191,7 @@ public class JSONObjectMapper {
* @param jsonObject {@link JSONObject}
*/
private void mapFromTokener(final JSONTokener x, final JSONConfig config, final JSONObject jsonObject) {
- JSONParser.of(x, config).parseTo(jsonObject, this.predicate);
+ OldJSONParser.of(x, config).parseTo(jsonObject, this.predicate);
}
/**
diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/reader/JSONParser.java b/hutool-json/src/main/java/org/dromara/hutool/json/reader/JSONParser.java
index cbbf3008c..95eedb5f0 100644
--- a/hutool-json/src/main/java/org/dromara/hutool/json/reader/JSONParser.java
+++ b/hutool-json/src/main/java/org/dromara/hutool/json/reader/JSONParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2024 Hutool Team and hutool.cn
+ * 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.
@@ -16,7 +16,6 @@
package org.dromara.hutool.json.reader;
-import org.dromara.hutool.core.lang.mutable.Mutable;
import org.dromara.hutool.core.lang.mutable.MutableEntry;
import org.dromara.hutool.core.text.CharUtil;
import org.dromara.hutool.json.*;
@@ -31,7 +30,7 @@ import java.util.function.Predicate;
*
*
* @author looly
- * @since 5.8.0
+ * @since 6.0.0
*/
public class JSONParser {
@@ -51,6 +50,7 @@ public class JSONParser {
*/
private final JSONConfig config;
private final JSONTokener tokener;
+ private Predicate> predicate;
/**
* 构造
@@ -73,72 +73,94 @@ public class JSONParser {
}
/**
- * 是否结束
+ * 获取下一个值,可以是:
+ *
+ * JSONObject
+ * JSONArray
+ * JSONPrimitive
+ * null
+ *
*
- * @return 是否结束
+ * @return JSON值
*/
- public boolean end() {
- return this.tokener.end();
+ public JSON nextValue() {
+ return nextValue(tokener.nextClean());
}
- // region parseTo
+ /**
+ * 获取下一个值,可以是:
+ *
+ * JSONObject
+ * JSONArray
+ * JSONPrimitive
+ * null
+ *
+ *
+ * @return JSON值
+ */
+ private JSON nextValue(final char c) {
+ switch (c) {
+ case CharUtil.DELIM_START:
+ final JSONObject jsonObject = new JSONObject(tokener, config);
+ nextJSONObject(jsonObject);
+ return jsonObject;
+ case CharUtil.BRACKET_START:
+ final JSONArray jsonArray = new JSONArray(tokener, config);
+ nextJSONArray(jsonArray);
+ return jsonArray;
+ default:
+ return nextJSONPrimitive(c);
+ }
+ }
/**
- * 解析{@link JSONTokener}中的字符到目标的{@link JSONObject}中
+ * 解析为JSONObject
*
- * @param jsonObject {@link JSONObject}
- * @param predicate 键值对过滤编辑器,可以通过实现此接口,完成解析前对键值对的过滤和修改操作,{@code null}表示不过滤,{@link Predicate#test(Object)}为{@code true}保留
+ * @param jsonObject JSON对象
*/
- public void parseTo(final JSONObject jsonObject, final Predicate> predicate) {
+ private void nextJSONObject(final JSONObject jsonObject) {
final JSONTokener tokener = this.tokener;
- if (tokener.nextClean() != '{') {
- throw tokener.syntaxError("A JSONObject text must begin with '{'");
- }
-
- char prev;
char c;
String key;
- while (true) {
- prev = tokener.getPrevious();
+ for (; ; ) {
c = tokener.nextClean();
- switch (c) {
- case 0:
- throw tokener.syntaxError("A JSONObject text must end with '}'");
- case '}':
- return;
- case '{':
- case '[':
- if (prev == '{') {
- throw tokener.syntaxError("A JSONObject can not directly nest another JSONObject or JSONArray.");
- }
- default:
- tokener.back();
- key = tokener.nextString();
+ if (c == CharUtil.DELIM_END) {// 对象结束
+ return;
+ } else {
+ key = tokener.nextKey(c);
}
// The key is followed by ':'.
+ tokener.nextColon();
- c = tokener.nextClean();
- if (c != ':') {
- throw tokener.syntaxError("Expected a ':' after a key");
+ // 过滤并设置键值对
+ Object value = nextValue();
+ // 添加前置过滤,通过MutablePair实现过滤、修改键值对等
+ if (null != predicate) {
+ final MutableEntry