mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-19 03:01:48 +08:00
add JSONParser
This commit is contained in:
parent
7debdcef60
commit
1f705e0e1f
@ -143,7 +143,7 @@ public final class InternalJSONUtil {
|
|||||||
* @param value 值
|
* @param value 值
|
||||||
* @param predicate 属性过滤器,{@link Predicate#test(Object)}为{@code true}保留
|
* @param predicate 属性过滤器,{@link Predicate#test(Object)}为{@code true}保留
|
||||||
*/
|
*/
|
||||||
public static void propertyPut(final JSONObject jsonObject, final Object key, final Object value, final Predicate<MutableEntry<String, Object>> predicate) {
|
public static void propertyPut(final JSONObject jsonObject, final Object key, final Object value, final Predicate<MutableEntry<Object, Object>> predicate) {
|
||||||
final String[] path = SplitUtil.splitToArray(ConvertUtil.toStr(key), StrUtil.DOT);
|
final String[] path = SplitUtil.splitToArray(ConvertUtil.toStr(key), StrUtil.DOT);
|
||||||
final int last = path.length - 1;
|
final int last = path.length - 1;
|
||||||
JSONObject target = jsonObject;
|
JSONObject target = jsonObject;
|
||||||
|
@ -164,7 +164,7 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
|
|||||||
* @throws JSONException 非数组或集合
|
* @throws JSONException 非数组或集合
|
||||||
* @since 5.8.0
|
* @since 5.8.0
|
||||||
*/
|
*/
|
||||||
public JSONArray(final Object object, final JSONConfig jsonConfig, final Predicate<Mutable<Object>> predicate) throws JSONException {
|
public JSONArray(final Object object, final JSONConfig jsonConfig, final Predicate<MutableEntry<Object, Object>> predicate) throws JSONException {
|
||||||
this(DEFAULT_CAPACITY, jsonConfig);
|
this(DEFAULT_CAPACITY, jsonConfig);
|
||||||
JSONArrayMapper.of(object, predicate).mapTo(this);
|
JSONArrayMapper.of(object, predicate).mapTo(this);
|
||||||
}
|
}
|
||||||
@ -201,7 +201,11 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object get(final int index) {
|
public Object get(final int index) {
|
||||||
return this.rawList.get(index);
|
Object value = this.rawList.get(index);
|
||||||
|
if(value instanceof JSONPrimitive){
|
||||||
|
value = ((JSONPrimitive) value).getValue();
|
||||||
|
}
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -152,7 +152,7 @@ public class JSONObject extends MapWrapper<String, Object> implements JSON, JSON
|
|||||||
* @param predicate 键值对过滤编辑器,可以通过实现此接口,完成解析前对键值对的过滤和修改操作,{@code null}表示不过滤,{@link Predicate#test(Object)}为{@code true}保留
|
* @param predicate 键值对过滤编辑器,可以通过实现此接口,完成解析前对键值对的过滤和修改操作,{@code null}表示不过滤,{@link Predicate#test(Object)}为{@code true}保留
|
||||||
* @since 5.8.0
|
* @since 5.8.0
|
||||||
*/
|
*/
|
||||||
public JSONObject(final Object source, final JSONConfig config, final Predicate<MutableEntry<String, Object>> predicate) {
|
public JSONObject(final Object source, final JSONConfig config, final Predicate<MutableEntry<Object, Object>> predicate) {
|
||||||
this(DEFAULT_CAPACITY, config);
|
this(DEFAULT_CAPACITY, config);
|
||||||
JSONObjectMapper.of(source, predicate).mapTo(this);
|
JSONObjectMapper.of(source, predicate).mapTo(this);
|
||||||
}
|
}
|
||||||
@ -200,7 +200,16 @@ public class JSONObject extends MapWrapper<String, Object> implements JSON, JSON
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getObj(final String key, final Object defaultValue) {
|
public Object getObj(final String key, final Object defaultValue) {
|
||||||
return this.getOrDefault(key, defaultValue);
|
return getOrDefault(key, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getOrDefault(final Object key, final Object defaultValue) {
|
||||||
|
Object value = super.getOrDefault(key, defaultValue);
|
||||||
|
if(value instanceof JSONPrimitive){
|
||||||
|
value = ((JSONPrimitive) value).getValue();
|
||||||
|
}
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -268,7 +277,7 @@ public class JSONObject extends MapWrapper<String, Object> implements JSON, JSON
|
|||||||
* @throws JSONException 值是无穷数字、键重复抛出异常
|
* @throws JSONException 值是无穷数字、键重复抛出异常
|
||||||
* @since 5.8.0
|
* @since 5.8.0
|
||||||
*/
|
*/
|
||||||
public JSONObject set(final String key, final Object value, final Predicate<MutableEntry<String, Object>> predicate) throws JSONException {
|
public JSONObject set(final String key, final Object value, final Predicate<MutableEntry<Object, Object>> predicate) throws JSONException {
|
||||||
put(key, value, predicate, config().isCheckDuplicate());
|
put(key, value, predicate, config().isCheckDuplicate());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -284,7 +293,7 @@ public class JSONObject extends MapWrapper<String, Object> implements JSON, JSON
|
|||||||
* @throws JSONException 值是无穷数字抛出此异常
|
* @throws JSONException 值是无穷数字抛出此异常
|
||||||
* @since 5.8.0
|
* @since 5.8.0
|
||||||
*/
|
*/
|
||||||
public JSONObject set(final String key, final Object value, final Predicate<MutableEntry<String, Object>> predicate, final boolean checkDuplicate) throws JSONException {
|
public JSONObject set(final String key, final Object value, final Predicate<MutableEntry<Object, Object>> predicate, final boolean checkDuplicate) throws JSONException {
|
||||||
put(key, value, predicate, checkDuplicate);
|
put(key, value, predicate, checkDuplicate);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -343,13 +352,13 @@ public class JSONObject extends MapWrapper<String, Object> implements JSON, JSON
|
|||||||
* @throws JSONException 如果给定键为{@code null}或者键对应的值存在且为非JSONArray
|
* @throws JSONException 如果给定键为{@code null}或者键对应的值存在且为非JSONArray
|
||||||
* @since 6.0.0
|
* @since 6.0.0
|
||||||
*/
|
*/
|
||||||
public JSONObject append(String key, Object value, final Predicate<MutableEntry<String, Object>> predicate) throws JSONException {
|
public JSONObject append(String key, Object value, final Predicate<MutableEntry<Object, Object>> predicate) throws JSONException {
|
||||||
// 添加前置过滤,通过MutablePair实现过滤、修改键值对等
|
// 添加前置过滤,通过MutablePair实现过滤、修改键值对等
|
||||||
if (null != predicate) {
|
if (null != predicate) {
|
||||||
final MutableEntry<String, Object> pair = new MutableEntry<>(key, value);
|
final MutableEntry<Object, Object> pair = new MutableEntry<>(key, value);
|
||||||
if (predicate.test(pair)) {
|
if (predicate.test(pair)) {
|
||||||
// 使用修改后的键值对
|
// 使用修改后的键值对
|
||||||
key = pair.getKey();
|
key = (String) pair.getKey();
|
||||||
value = pair.getValue();
|
value = pair.getValue();
|
||||||
} else {
|
} else {
|
||||||
// 键值对被过滤
|
// 键值对被过滤
|
||||||
@ -465,17 +474,17 @@ public class JSONObject extends MapWrapper<String, Object> implements JSON, JSON
|
|||||||
* @throws JSONException 值是无穷数字抛出此异常
|
* @throws JSONException 值是无穷数字抛出此异常
|
||||||
* @since 5.8.0
|
* @since 5.8.0
|
||||||
*/
|
*/
|
||||||
private Object put(String key, Object value, final Predicate<MutableEntry<String, Object>> predicate, final boolean checkDuplicate) throws JSONException {
|
private Object put(String key, Object value, final Predicate<MutableEntry<Object, Object>> predicate, final boolean checkDuplicate) throws JSONException {
|
||||||
if (null == key) {
|
if (null == key) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加前置过滤,通过MutablePair实现过滤、修改键值对等
|
// 添加前置过滤,通过MutablePair实现过滤、修改键值对等
|
||||||
if (null != predicate) {
|
if (null != predicate) {
|
||||||
final MutableEntry<String, Object> pair = new MutableEntry<>(key, value);
|
final MutableEntry<Object, Object> pair = new MutableEntry<>(key, value);
|
||||||
if (predicate.test(pair)) {
|
if (predicate.test(pair)) {
|
||||||
// 使用修改后的键值对
|
// 使用修改后的键值对
|
||||||
key = pair.getKey();
|
key = (String) pair.getKey();
|
||||||
value = pair.getValue();
|
value = pair.getValue();
|
||||||
} else {
|
} else {
|
||||||
// 键值对被过滤
|
// 键值对被过滤
|
||||||
|
@ -24,6 +24,7 @@ import org.dromara.hutool.json.writer.JSONWriter;
|
|||||||
|
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -107,6 +108,11 @@ public class JSONPrimitive implements JSON {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T convert(final Type targetType, final Object value, final T defaultValue) {
|
||||||
|
return JSON.super.convert(targetType, this.value, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Writer write(final Writer writer, final int indentFactor, final int indent, final Predicate<MutableEntry<Object, Object>> predicate) throws JSONException {
|
public Writer write(final Writer writer, final int indentFactor, final int indent, final Predicate<MutableEntry<Object, Object>> predicate) throws JSONException {
|
||||||
final Object value = this.value;
|
final Object value = this.value;
|
||||||
|
@ -30,7 +30,7 @@ import org.dromara.hutool.core.reflect.TypeUtil;
|
|||||||
import org.dromara.hutool.core.reflect.kotlin.KClassUtil;
|
import org.dromara.hutool.core.reflect.kotlin.KClassUtil;
|
||||||
import org.dromara.hutool.core.text.StrUtil;
|
import org.dromara.hutool.core.text.StrUtil;
|
||||||
import org.dromara.hutool.json.*;
|
import org.dromara.hutool.json.*;
|
||||||
import org.dromara.hutool.json.reader.OldJSONParser;
|
import org.dromara.hutool.json.reader.JSONParser;
|
||||||
import org.dromara.hutool.json.reader.JSONTokener;
|
import org.dromara.hutool.json.reader.JSONTokener;
|
||||||
import org.dromara.hutool.json.serializer.*;
|
import org.dromara.hutool.json.serializer.*;
|
||||||
|
|
||||||
@ -202,16 +202,8 @@ public class JSONConverter implements Converter, Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RFC8259,JSON字符串值、number, boolean, or null
|
// RFC8259,JSON字符串值、number, boolean, or null
|
||||||
final OldJSONParser jsonParser = OldJSONParser.of(new JSONTokener(jsonStr), config);
|
final JSONParser jsonParser = JSONParser.of(new JSONTokener(jsonStr), config);
|
||||||
final Object value = jsonParser.nextValue();
|
return jsonParser.parse();
|
||||||
if (jsonParser.getTokener().nextClean() != JSONTokener.EOF) {
|
|
||||||
// 对于用户提供的未转义字符串导致解析未结束,报错
|
|
||||||
throw new JSONException("JSON format error: {}", jsonStr);
|
|
||||||
}
|
|
||||||
if(null == value || value instanceof JSON){
|
|
||||||
return (JSON) value;
|
|
||||||
}
|
|
||||||
return new JSONPrimitive(value, config);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------- Private method start
|
// ----------------------------------------------------------- Private method start
|
||||||
|
@ -19,12 +19,12 @@ package org.dromara.hutool.json.mapper;
|
|||||||
import org.dromara.hutool.core.array.ArrayUtil;
|
import org.dromara.hutool.core.array.ArrayUtil;
|
||||||
import org.dromara.hutool.core.collection.iter.ArrayIter;
|
import org.dromara.hutool.core.collection.iter.ArrayIter;
|
||||||
import org.dromara.hutool.core.io.IoUtil;
|
import org.dromara.hutool.core.io.IoUtil;
|
||||||
import org.dromara.hutool.core.lang.mutable.Mutable;
|
import org.dromara.hutool.core.lang.mutable.MutableEntry;
|
||||||
import org.dromara.hutool.core.text.StrUtil;
|
import org.dromara.hutool.core.text.StrUtil;
|
||||||
import org.dromara.hutool.json.JSONArray;
|
import org.dromara.hutool.json.JSONArray;
|
||||||
import org.dromara.hutool.json.JSONConfig;
|
import org.dromara.hutool.json.JSONConfig;
|
||||||
import org.dromara.hutool.json.JSONException;
|
import org.dromara.hutool.json.JSONException;
|
||||||
import org.dromara.hutool.json.reader.OldJSONParser;
|
import org.dromara.hutool.json.reader.JSONParser;
|
||||||
import org.dromara.hutool.json.reader.JSONTokener;
|
import org.dromara.hutool.json.reader.JSONTokener;
|
||||||
import org.dromara.hutool.json.serializer.JSONSerializer;
|
import org.dromara.hutool.json.serializer.JSONSerializer;
|
||||||
import org.dromara.hutool.json.serializer.SerializerManager;
|
import org.dromara.hutool.json.serializer.SerializerManager;
|
||||||
@ -58,12 +58,12 @@ public class JSONArrayMapper {
|
|||||||
* @param predicate 值过滤编辑器,可以通过实现此接口,完成解析前对值的过滤和修改操作,{@code null}表示不过滤,,{@link Predicate#test(Object)}为{@code true}保留
|
* @param predicate 值过滤编辑器,可以通过实现此接口,完成解析前对值的过滤和修改操作,{@code null}表示不过滤,,{@link Predicate#test(Object)}为{@code true}保留
|
||||||
* @return ObjectMapper
|
* @return ObjectMapper
|
||||||
*/
|
*/
|
||||||
public static JSONArrayMapper of(final Object source, final Predicate<Mutable<Object>> predicate) {
|
public static JSONArrayMapper of(final Object source, final Predicate<MutableEntry<Object, Object>> predicate) {
|
||||||
return new JSONArrayMapper(source, predicate);
|
return new JSONArrayMapper(source, predicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Object source;
|
private final Object source;
|
||||||
private final Predicate<Mutable<Object>> predicate;
|
private final Predicate<MutableEntry<Object, Object>> predicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
@ -71,7 +71,7 @@ public class JSONArrayMapper {
|
|||||||
* @param source 来源对象
|
* @param source 来源对象
|
||||||
* @param predicate 值过滤编辑器,可以通过实现此接口,完成解析前对值的过滤和修改操作,{@code null}表示不过滤,,{@link Predicate#test(Object)}为{@code true}保留
|
* @param predicate 值过滤编辑器,可以通过实现此接口,完成解析前对值的过滤和修改操作,{@code null}表示不过滤,,{@link Predicate#test(Object)}为{@code true}保留
|
||||||
*/
|
*/
|
||||||
public JSONArrayMapper(final Object source, final Predicate<Mutable<Object>> predicate) {
|
public JSONArrayMapper(final Object source, final Predicate<MutableEntry<Object, Object>> predicate) {
|
||||||
this.source = source;
|
this.source = source;
|
||||||
this.predicate = predicate;
|
this.predicate = predicate;
|
||||||
}
|
}
|
||||||
@ -82,7 +82,6 @@ public class JSONArrayMapper {
|
|||||||
* @param jsonArray 目标{@link JSONArray}
|
* @param jsonArray 目标{@link JSONArray}
|
||||||
* @throws JSONException 非数组或集合
|
* @throws JSONException 非数组或集合
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void mapTo(final JSONArray jsonArray) throws JSONException {
|
public void mapTo(final JSONArray jsonArray) throws JSONException {
|
||||||
final Object source = this.source;
|
final Object source = this.source;
|
||||||
if (null == source) {
|
if (null == source) {
|
||||||
@ -98,8 +97,8 @@ public class JSONArrayMapper {
|
|||||||
|
|
||||||
if (source instanceof JSONTokener) {
|
if (source instanceof JSONTokener) {
|
||||||
mapFromTokener((JSONTokener) source, JSONConfig.of(), jsonArray);
|
mapFromTokener((JSONTokener) source, JSONConfig.of(), jsonArray);
|
||||||
}if (source instanceof OldJSONParser) {
|
}if (source instanceof JSONParser) {
|
||||||
((OldJSONParser)source).parseTo(jsonArray, this.predicate);
|
((JSONParser)source).parseTo(jsonArray);
|
||||||
} else if (source instanceof CharSequence) {
|
} else if (source instanceof CharSequence) {
|
||||||
// JSON字符串
|
// JSON字符串
|
||||||
mapFromStr((CharSequence) source, jsonArray);
|
mapFromStr((CharSequence) source, jsonArray);
|
||||||
@ -139,7 +138,16 @@ public class JSONArrayMapper {
|
|||||||
next = iter.next();
|
next = iter.next();
|
||||||
// 检查循环引用
|
// 检查循环引用
|
||||||
if (next != source) {
|
if (next != source) {
|
||||||
jsonArray.add(next, predicate);
|
if(null != this.predicate){
|
||||||
|
final MutableEntry<Object, Object> entry = MutableEntry.of(jsonArray.size(), next);
|
||||||
|
if (predicate.test(entry)) {
|
||||||
|
// 使用修改后的键值对
|
||||||
|
next = entry.getValue();
|
||||||
|
jsonArray.add(next);
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
jsonArray.add(next);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -164,6 +172,6 @@ public class JSONArrayMapper {
|
|||||||
* @param jsonArray {@link JSONArray}
|
* @param jsonArray {@link JSONArray}
|
||||||
*/
|
*/
|
||||||
private void mapFromTokener(final JSONTokener x, final JSONConfig config, final JSONArray jsonArray) {
|
private void mapFromTokener(final JSONTokener x, final JSONConfig config, final JSONArray jsonArray) {
|
||||||
OldJSONParser.of(x, config).parseTo(jsonArray, this.predicate);
|
JSONParser.of(x, config).setPredicate(this.predicate).parseTo(jsonArray);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.reflect.method.MethodUtil;
|
||||||
import org.dromara.hutool.core.text.StrUtil;
|
import org.dromara.hutool.core.text.StrUtil;
|
||||||
import org.dromara.hutool.json.*;
|
import org.dromara.hutool.json.*;
|
||||||
import org.dromara.hutool.json.reader.OldJSONParser;
|
import org.dromara.hutool.json.reader.JSONParser;
|
||||||
import org.dromara.hutool.json.reader.JSONTokener;
|
import org.dromara.hutool.json.reader.JSONTokener;
|
||||||
import org.dromara.hutool.json.serializer.JSONSerializer;
|
import org.dromara.hutool.json.serializer.JSONSerializer;
|
||||||
import org.dromara.hutool.json.serializer.SerializerManager;
|
import org.dromara.hutool.json.serializer.SerializerManager;
|
||||||
@ -66,12 +66,12 @@ public class JSONObjectMapper {
|
|||||||
* @param predicate 键值对过滤编辑器,可以通过实现此接口,完成解析前对键值对的过滤和修改操作,{@link Predicate#test(Object)}为{@code true}保留
|
* @param predicate 键值对过滤编辑器,可以通过实现此接口,完成解析前对键值对的过滤和修改操作,{@link Predicate#test(Object)}为{@code true}保留
|
||||||
* @return ObjectMapper
|
* @return ObjectMapper
|
||||||
*/
|
*/
|
||||||
public static JSONObjectMapper of(final Object source, final Predicate<MutableEntry<String, Object>> predicate) {
|
public static JSONObjectMapper of(final Object source, final Predicate<MutableEntry<Object, Object>> predicate) {
|
||||||
return new JSONObjectMapper(source, predicate);
|
return new JSONObjectMapper(source, predicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Object source;
|
private final Object source;
|
||||||
private final Predicate<MutableEntry<String, Object>> predicate;
|
private final Predicate<MutableEntry<Object, Object>> predicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
@ -79,7 +79,7 @@ public class JSONObjectMapper {
|
|||||||
* @param source 来源对象
|
* @param source 来源对象
|
||||||
* @param predicate 键值对过滤编辑器,可以通过实现此接口,完成解析前对键值对的过滤和修改操作,{@link Predicate#test(Object)}为{@code true}保留
|
* @param predicate 键值对过滤编辑器,可以通过实现此接口,完成解析前对键值对的过滤和修改操作,{@link Predicate#test(Object)}为{@code true}保留
|
||||||
*/
|
*/
|
||||||
public JSONObjectMapper(final Object source, final Predicate<MutableEntry<String, Object>> predicate) {
|
public JSONObjectMapper(final Object source, final Predicate<MutableEntry<Object, Object>> predicate) {
|
||||||
this.source = source;
|
this.source = source;
|
||||||
this.predicate = predicate;
|
this.predicate = predicate;
|
||||||
}
|
}
|
||||||
@ -111,9 +111,9 @@ public class JSONObjectMapper {
|
|||||||
if (source instanceof JSONTokener) {
|
if (source instanceof JSONTokener) {
|
||||||
// JSONTokener
|
// JSONTokener
|
||||||
mapFromTokener((JSONTokener) source, jsonObject.config(), jsonObject);
|
mapFromTokener((JSONTokener) source, jsonObject.config(), jsonObject);
|
||||||
}if (source instanceof OldJSONParser) {
|
}if (source instanceof JSONParser) {
|
||||||
// JSONParser
|
// JSONParser
|
||||||
((OldJSONParser) source).parseTo(jsonObject, this.predicate);
|
((JSONParser) source).parseTo(jsonObject);
|
||||||
} else if (source instanceof Map) {
|
} else if (source instanceof Map) {
|
||||||
// Map
|
// Map
|
||||||
for (final Map.Entry<?, ?> e : ((Map<?, ?>) source).entrySet()) {
|
for (final Map.Entry<?, ?> e : ((Map<?, ?>) source).entrySet()) {
|
||||||
@ -180,7 +180,7 @@ public class JSONObjectMapper {
|
|||||||
JSONXMLParser.of(ParseConfig.of(), this.predicate).parseJSONObject(jsonStr, jsonObject);
|
JSONXMLParser.of(ParseConfig.of(), this.predicate).parseJSONObject(jsonStr, jsonObject);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mapFromTokener(new JSONTokener(StrUtil.trim(source)), jsonObject.config(), jsonObject);
|
mapFromTokener(new JSONTokener(source), jsonObject.config(), jsonObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -191,7 +191,7 @@ public class JSONObjectMapper {
|
|||||||
* @param jsonObject {@link JSONObject}
|
* @param jsonObject {@link JSONObject}
|
||||||
*/
|
*/
|
||||||
private void mapFromTokener(final JSONTokener x, final JSONConfig config, final JSONObject jsonObject) {
|
private void mapFromTokener(final JSONTokener x, final JSONConfig config, final JSONObject jsonObject) {
|
||||||
OldJSONParser.of(x, config).parseTo(jsonObject, this.predicate);
|
JSONParser.of(x, config).setPredicate(this.predicate).parseTo(jsonObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,10 +24,12 @@ import java.util.function.Predicate;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* JSON字符串解析器,实现:
|
* JSON字符串解析器,实现:
|
||||||
* <ul>
|
* <pre>{@code
|
||||||
* <li>JSON字符串 --> {@link JSONTokener} --> {@link JSONObject}</li>
|
* JSONTokener
|
||||||
* <li>JSON字符串 --> {@link JSONTokener} --> {@link JSONArray}</li>
|
* 字符串 -------------> JSONObject
|
||||||
* </ul>
|
* 字符串 -------------> JSONArray
|
||||||
|
* 字符串 -------------> JSONPrimitive
|
||||||
|
* }</pre>
|
||||||
*
|
*
|
||||||
* @author looly
|
* @author looly
|
||||||
* @since 6.0.0
|
* @since 6.0.0
|
||||||
@ -50,6 +52,10 @@ public class JSONParser {
|
|||||||
*/
|
*/
|
||||||
private final JSONConfig config;
|
private final JSONConfig config;
|
||||||
private final JSONTokener tokener;
|
private final JSONTokener tokener;
|
||||||
|
/**
|
||||||
|
* 过滤器,用于过滤或修改键值对,返回null表示忽略此键值对,返回非null表示修改后返回<br>
|
||||||
|
* entry中,key在JSONObject中为name,在JSONArray中为index
|
||||||
|
*/
|
||||||
private Predicate<MutableEntry<Object, Object>> predicate;
|
private Predicate<MutableEntry<Object, Object>> predicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -73,18 +79,14 @@ public class JSONParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取下一个值,可以是:
|
* 设置过滤器,用于过滤或修改键值对,返回null表示忽略此键值对,返回非null表示修改后返回
|
||||||
* <pre>
|
|
||||||
* JSONObject
|
|
||||||
* JSONArray
|
|
||||||
* JSONPrimitive
|
|
||||||
* null
|
|
||||||
* </pre>
|
|
||||||
*
|
*
|
||||||
* @return JSON值
|
* @param predicate 过滤器,用于过滤或修改键值对,返回null表示忽略此键值对,返回非null表示修改后返回
|
||||||
|
* @return this
|
||||||
*/
|
*/
|
||||||
public JSON nextValue() {
|
public JSONParser setPredicate(final Predicate<MutableEntry<Object, Object>> predicate) {
|
||||||
return nextValue(tokener.nextClean());
|
this.predicate = predicate;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -98,34 +100,80 @@ public class JSONParser {
|
|||||||
*
|
*
|
||||||
* @return JSON值
|
* @return JSON值
|
||||||
*/
|
*/
|
||||||
private JSON nextValue(final char c) {
|
public JSON parse() {
|
||||||
switch (c) {
|
return nextJSON(tokener.nextClean());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析为JSONObject或JSONArray,解析值包括:
|
||||||
|
* <pre>
|
||||||
|
* JSONObject
|
||||||
|
* JSONArray
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @param json JSON对象或数组,用于存储解析结果
|
||||||
|
*/
|
||||||
|
public void parseTo(final JSON json) {
|
||||||
|
if(null == json){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (tokener.nextClean()) {
|
||||||
case CharUtil.DELIM_START:
|
case CharUtil.DELIM_START:
|
||||||
final JSONObject jsonObject = new JSONObject(tokener, config);
|
nextTo((JSONObject) json);
|
||||||
nextJSONObject(jsonObject);
|
break;
|
||||||
return jsonObject;
|
|
||||||
case CharUtil.BRACKET_START:
|
case CharUtil.BRACKET_START:
|
||||||
final JSONArray jsonArray = new JSONArray(tokener, config);
|
nextTo((JSONArray) json);
|
||||||
nextJSONArray(jsonArray);
|
break;
|
||||||
return jsonArray;
|
|
||||||
default:
|
default:
|
||||||
return nextJSONPrimitive(c);
|
throw new JSONException("Unsupported: " + json.getClass());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析为JSONObject
|
* 获取下一个值,可以是:
|
||||||
|
* <pre>
|
||||||
|
* JSONObject
|
||||||
|
* JSONArray
|
||||||
|
* JSONPrimitive
|
||||||
|
* null
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @return JSON值
|
||||||
|
*/
|
||||||
|
private JSON nextJSON(final char firstChar) {
|
||||||
|
final JSON result;
|
||||||
|
switch (firstChar) {
|
||||||
|
case CharUtil.DELIM_START:
|
||||||
|
final JSONObject jsonObject = new JSONObject(config);
|
||||||
|
nextTo(jsonObject);
|
||||||
|
result = jsonObject;
|
||||||
|
break;
|
||||||
|
case CharUtil.BRACKET_START:
|
||||||
|
final JSONArray jsonArray = new JSONArray(config);
|
||||||
|
nextTo(jsonArray);
|
||||||
|
result = jsonArray;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result = nextJSONPrimitive(firstChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析下一个值为JSONObject,第一个字符必须读取完后再调用此方法
|
||||||
*
|
*
|
||||||
* @param jsonObject JSON对象
|
* @param jsonObject JSON对象
|
||||||
*/
|
*/
|
||||||
private void nextJSONObject(final JSONObject jsonObject) {
|
private void nextTo(final JSONObject jsonObject) {
|
||||||
final JSONTokener tokener = this.tokener;
|
final JSONTokener tokener = this.tokener;
|
||||||
|
|
||||||
char c;
|
char c;
|
||||||
String key;
|
String key;
|
||||||
for (; ; ) {
|
for (; ; ) {
|
||||||
c = tokener.nextClean();
|
c = tokener.nextClean();
|
||||||
if (c == CharUtil.DELIM_END) {// 对象结束
|
if (c == CharUtil.DELIM_END) {
|
||||||
|
// 对象结束
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
key = tokener.nextKey(c);
|
key = tokener.nextKey(c);
|
||||||
@ -135,7 +183,7 @@ public class JSONParser {
|
|||||||
tokener.nextColon();
|
tokener.nextColon();
|
||||||
|
|
||||||
// 过滤并设置键值对
|
// 过滤并设置键值对
|
||||||
Object value = nextValue();
|
Object value = parse();
|
||||||
// 添加前置过滤,通过MutablePair实现过滤、修改键值对等
|
// 添加前置过滤,通过MutablePair实现过滤、修改键值对等
|
||||||
if (null != predicate) {
|
if (null != predicate) {
|
||||||
final MutableEntry<Object, Object> pair = new MutableEntry<>(key, value);
|
final MutableEntry<Object, Object> pair = new MutableEntry<>(key, value);
|
||||||
@ -169,31 +217,30 @@ public class JSONParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析为JSONArray
|
* 解析下一个值为JSONArray,第一个字符必须读取完后再调用此方法
|
||||||
*
|
*
|
||||||
* @param jsonArray JSON数组
|
* @param jsonArray JSON数组
|
||||||
*/
|
*/
|
||||||
private void nextJSONArray(final JSONArray jsonArray) {
|
private void nextTo(final JSONArray jsonArray) {
|
||||||
final JSONTokener tokener = this.tokener;
|
final JSONTokener tokener = this.tokener;
|
||||||
char c;
|
char c;
|
||||||
for (; ; ) {
|
for (; ; ) {
|
||||||
c = tokener.nextClean();
|
c = tokener.nextClean();
|
||||||
switch (c) {
|
if (c == CharUtil.BRACKET_END) {
|
||||||
case CharUtil.BRACKET_END:
|
// 数组结束
|
||||||
return;
|
return;
|
||||||
case CharUtil.COMMA:
|
} else {
|
||||||
jsonArray.add(nextValue());
|
// ,value or value
|
||||||
default:
|
Object value = nextJSON(CharUtil.COMMA == c ? tokener.nextClean() : c);
|
||||||
Object value = CharUtil.COMMA == c ? nextValue() : nextValue(c);
|
|
||||||
if (null != predicate) {
|
if (null != predicate) {
|
||||||
// 使用过滤器
|
// 使用过滤器
|
||||||
final MutableEntry<Object, Object> pair = MutableEntry.of(jsonArray.size(), value);
|
final MutableEntry<Object, Object> entry = MutableEntry.of(jsonArray.size(), value);
|
||||||
if (predicate.test(pair)) {
|
if (predicate.test(entry)) {
|
||||||
// 使用修改后的键值对
|
// 使用修改后的键值对
|
||||||
value = pair.getValue();
|
value = entry.getValue();
|
||||||
jsonArray.add(value);
|
jsonArray.add(value);
|
||||||
}
|
}
|
||||||
}else {
|
} else {
|
||||||
jsonArray.add(value);
|
jsonArray.add(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -208,17 +255,17 @@ public class JSONParser {
|
|||||||
* string
|
* string
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @param c 值类型
|
* @param firstChar 第一个字符,引号或字母
|
||||||
* @return JSONPrimitive或{@code null}
|
* @return JSONPrimitive或{@code null}
|
||||||
*/
|
*/
|
||||||
private JSONPrimitive nextJSONPrimitive(final char c) {
|
private JSONPrimitive nextJSONPrimitive(final char firstChar) {
|
||||||
switch (c) {
|
switch (firstChar) {
|
||||||
case CharUtil.DOUBLE_QUOTES:
|
case CharUtil.DOUBLE_QUOTES:
|
||||||
case CharUtil.SINGLE_QUOTE:
|
case CharUtil.SINGLE_QUOTE:
|
||||||
// 引号包围,表示字符串值
|
// 引号包围,表示字符串值
|
||||||
return new JSONPrimitive(tokener.nextWrapString(c));
|
return new JSONPrimitive(tokener.nextWrapString(firstChar));
|
||||||
default:
|
default:
|
||||||
final Object value = InternalJSONUtil.parseValueFromString(tokener.nextUnwrapString(c));
|
final Object value = InternalJSONUtil.parseValueFromString(tokener.nextUnwrapString(firstChar));
|
||||||
// 非引号包围,可能为boolean、数字、null等
|
// 非引号包围,可能为boolean、数字、null等
|
||||||
return null == value ? null : new JSONPrimitive(value);
|
return null == value ? null : new JSONPrimitive(value);
|
||||||
}
|
}
|
||||||
|
@ -128,6 +128,16 @@ public class JSONTokener extends ReaderWrapper {
|
|||||||
return this.eof && !this.usePrevious;
|
return this.eof && !this.usePrevious;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查是否到了结尾<br>
|
||||||
|
* 如果读取完毕后还有未读的字符,报错
|
||||||
|
*/
|
||||||
|
public void checkEnd(){
|
||||||
|
if(EOF != nextClean()){
|
||||||
|
throw syntaxError("Unread data");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 源字符串是否有更多的字符
|
* 源字符串是否有更多的字符
|
||||||
*
|
*
|
||||||
@ -244,7 +254,7 @@ public class JSONTokener extends ReaderWrapper {
|
|||||||
char c;
|
char c;
|
||||||
while (true) {
|
while (true) {
|
||||||
c = this.next();
|
c = this.next();
|
||||||
if (c == EOF || c > ' ') {
|
if (c == EOF || c > CharUtil.SPACE) {
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -258,14 +268,13 @@ public class JSONTokener extends ReaderWrapper {
|
|||||||
* @throws JSONException 非引号包裹的字符串
|
* @throws JSONException 非引号包裹的字符串
|
||||||
*/
|
*/
|
||||||
public String nextKey(final char c) throws JSONException {
|
public String nextKey(final char c) throws JSONException {
|
||||||
final char prev = this.previous;
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case JSONTokener.EOF:
|
case JSONTokener.EOF:
|
||||||
// 未关闭对象
|
// 未关闭对象
|
||||||
throw syntaxError("A JSONObject text must end with '}'");
|
throw syntaxError("A JSONObject text must end with '}'");
|
||||||
case CharUtil.DELIM_START:
|
case CharUtil.DELIM_START:
|
||||||
case CharUtil.BRACKET_END:
|
case CharUtil.BRACKET_START:
|
||||||
if (prev == CharUtil.DELIM_START) {
|
if (CharUtil.DELIM_START == this.previous) {
|
||||||
// 不允许嵌套对象,如{{}}或{[]}
|
// 不允许嵌套对象,如{{}}或{[]}
|
||||||
throw syntaxError("A JSONObject can not directly nest another JSONObject or JSONArray.");
|
throw syntaxError("A JSONObject can not directly nest another JSONObject or JSONArray.");
|
||||||
}
|
}
|
||||||
|
@ -124,7 +124,7 @@ public class OldJSONParser {
|
|||||||
throw tokener.syntaxError("Expected a ':' after a key");
|
throw tokener.syntaxError("Expected a ':' after a key");
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonObject.set(key, nextValue(), predicate);
|
jsonObject.set(key, nextValue(), null);
|
||||||
|
|
||||||
// Pairs are separated by ','.
|
// Pairs are separated by ','.
|
||||||
|
|
||||||
|
@ -32,5 +32,5 @@ public interface MatcherJSONSerializer<V> extends JSONSerializer<V> {
|
|||||||
* @param context JSON上下文
|
* @param context JSON上下文
|
||||||
* @return 是否匹配
|
* @return 是否匹配
|
||||||
*/
|
*/
|
||||||
boolean match(V bean, JSONContext context);
|
boolean match(Object bean, JSONContext context);
|
||||||
}
|
}
|
||||||
|
@ -44,9 +44,8 @@ public class TimeZoneSerializer implements MatcherJSONSerializer<TimeZone>, Matc
|
|||||||
return TimeZone.class.isAssignableFrom(TypeUtil.getClass(deserializeType));
|
return TimeZone.class.isAssignableFrom(TypeUtil.getClass(deserializeType));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("DataFlowIssue")
|
|
||||||
@Override
|
@Override
|
||||||
public boolean match(final TimeZone bean, final JSONContext context) {
|
public boolean match(final Object bean, final JSONContext context) {
|
||||||
return bean instanceof TimeZone;
|
return bean instanceof TimeZone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,12 +41,12 @@ public class JSONXMLParser {
|
|||||||
* @param predicate 键值对过滤编辑器,可以通过实现此接口,完成解析前对键值对的过滤和修改操作,{@link Predicate#test(Object)}为{@code true}保留
|
* @param predicate 键值对过滤编辑器,可以通过实现此接口,完成解析前对键值对的过滤和修改操作,{@link Predicate#test(Object)}为{@code true}保留
|
||||||
* @return JSONXMLParser
|
* @return JSONXMLParser
|
||||||
*/
|
*/
|
||||||
public static JSONXMLParser of(final ParseConfig parseConfig, final Predicate<MutableEntry<String, Object>> predicate) {
|
public static JSONXMLParser of(final ParseConfig parseConfig, final Predicate<MutableEntry<Object, Object>> predicate) {
|
||||||
return new JSONXMLParser(parseConfig, predicate);
|
return new JSONXMLParser(parseConfig, predicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ParseConfig parseConfig;
|
private final ParseConfig parseConfig;
|
||||||
private final Predicate<MutableEntry<String, Object>> predicate;
|
private final Predicate<MutableEntry<Object, Object>> predicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
@ -54,7 +54,7 @@ public class JSONXMLParser {
|
|||||||
* @param parseConfig 解析选项
|
* @param parseConfig 解析选项
|
||||||
* @param predicate 键值对过滤编辑器,可以通过实现此接口,完成解析前对键值对的过滤和修改操作,{@link Predicate#test(Object)}为{@code true}保留
|
* @param predicate 键值对过滤编辑器,可以通过实现此接口,完成解析前对键值对的过滤和修改操作,{@link Predicate#test(Object)}为{@code true}保留
|
||||||
*/
|
*/
|
||||||
public JSONXMLParser(final ParseConfig parseConfig, final Predicate<MutableEntry<String, Object>> predicate) {
|
public JSONXMLParser(final ParseConfig parseConfig, final Predicate<MutableEntry<Object, Object>> predicate) {
|
||||||
this.parseConfig = parseConfig;
|
this.parseConfig = parseConfig;
|
||||||
this.predicate = predicate;
|
this.predicate = predicate;
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ public class IssueI9DX5HTest {
|
|||||||
void xmlToJSONTest() {
|
void xmlToJSONTest() {
|
||||||
final String xml = "<GoodMsg>你好</GoodMsg>";
|
final String xml = "<GoodMsg>你好</GoodMsg>";
|
||||||
final JSONObject jsonObject = new JSONObject(xml, JSONConfig.of(), entry -> {
|
final JSONObject jsonObject = new JSONObject(xml, JSONConfig.of(), entry -> {
|
||||||
entry.setKey(StrUtil.toUnderlineCase(entry.getKey()));
|
entry.setKey(StrUtil.toUnderlineCase((CharSequence) entry.getKey()));
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -29,10 +29,7 @@ import org.dromara.hutool.json.test.bean.KeyBean;
|
|||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
@ -322,7 +319,7 @@ public class JSONArrayTest {
|
|||||||
if ("111".equals(o.getStr("id"))) {
|
if ("111".equals(o.getStr("id"))) {
|
||||||
o.set("name", "test1_edit");
|
o.set("name", "test1_edit");
|
||||||
}
|
}
|
||||||
mutable.set(o);
|
mutable.set(new AbstractMap.SimpleEntry<>(1, o));
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
assertEquals(2, array.size());
|
assertEquals(2, array.size());
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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.reader;
|
||||||
|
|
||||||
|
import org.dromara.hutool.json.JSON;
|
||||||
|
import org.dromara.hutool.json.JSONConfig;
|
||||||
|
import org.dromara.hutool.json.JSONObject;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class JSONParserTest {
|
||||||
|
@Test
|
||||||
|
void parseTest() {
|
||||||
|
final String jsonStr = " {\"a\": 1} ";
|
||||||
|
final JSONParser jsonParser = JSONParser.of(new JSONTokener(jsonStr), JSONConfig.of());
|
||||||
|
final JSON parse = jsonParser.parse();
|
||||||
|
Assertions.assertEquals("{\"a\":1}", parse.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void nextToTest() {
|
||||||
|
final String jsonStr = "{\"a\": 1}";
|
||||||
|
JSONParser.of(new JSONTokener(jsonStr), JSONConfig.of()).parseTo(new JSONObject());
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user