This commit is contained in:
Looly
2024-09-19 01:47:21 +08:00
parent c489cc7735
commit bc3f6cf1ee
35 changed files with 296 additions and 576 deletions

View File

@@ -113,9 +113,9 @@ public final class InternalJSONUtil {
return JSONUtil.parseObj(map).toString();
} else if (value instanceof Collection) {
final Collection<?> coll = (Collection<?>) value;
return new JSONArray(coll).toString();
return JSONUtil.parseArray(coll).toString();
} else if (ArrayUtil.isArray(value)) {
return new JSONArray(value).toString();
return JSONUtil.parseArray(value).toString();
} else {
return quote(value.toString());
}

View File

@@ -17,16 +17,12 @@
package org.dromara.hutool.json;
import org.dromara.hutool.core.collection.CollUtil;
import org.dromara.hutool.core.collection.ListWrapper;
import org.dromara.hutool.core.convert.ConvertUtil;
import org.dromara.hutool.core.convert.impl.ArrayConverter;
import org.dromara.hutool.core.lang.Validator;
import org.dromara.hutool.core.lang.mutable.Mutable;
import org.dromara.hutool.core.lang.mutable.MutableEntry;
import org.dromara.hutool.core.lang.mutable.MutableObj;
import org.dromara.hutool.core.text.StrJoiner;
import org.dromara.hutool.core.util.ObjUtil;
import org.dromara.hutool.json.mapper.JSONArrayMapper;
import org.dromara.hutool.json.mapper.JSONValueMapper;
import org.dromara.hutool.json.writer.JSONWriter;
import java.util.*;
@@ -43,7 +39,7 @@ import java.util.function.Predicate;
*
* @author looly
*/
public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, RandomAccess {
public class JSONArray extends ListWrapper<JSON> implements JSON, JSONGetter<Integer>, RandomAccess {
private static final long serialVersionUID = 2664900568717612292L;
/**
@@ -51,20 +47,12 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
*/
public static final int DEFAULT_CAPACITY = 10;
/**
* 持有原始数据的List
*/
private List<Object> rawList;
/**
* 配置项
*/
private JSONConfig config;
/**
* 对象转换和包装用于将Java对象和值转换为JSON值
*/
private JSONValueMapper valueMapper;
// region Constructors
// region ----- Constructors
/**
* 构造<br>
@@ -105,66 +93,8 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
* @since 4.1.19
*/
public JSONArray(final int initialCapacity, final JSONConfig config) {
this.rawList = new ArrayList<>(initialCapacity);
super(new ArrayList<>(initialCapacity));
this.config = ObjUtil.defaultIfNull(config, JSONConfig::of);
this.valueMapper = JSONValueMapper.of(this.config);
}
/**
* 从对象构造,忽略{@code null}的值<br>
* 支持以下类型的参数:
*
* <pre>
* 1. 数组
* 2. {@link Iterable}对象
* 3. JSON数组字符串
* </pre>
*
* @param object 数组或集合或JSON数组字符串
* @throws JSONException 非数组或集合
*/
public JSONArray(final Object object) throws JSONException {
this(object, JSONConfig.of());
}
/**
* 从对象构造<br>
* 支持以下类型的参数:
*
* <pre>
* 1. 数组
* 2. {@link Iterable}对象
* 3. JSON数组字符串
* </pre>
*
* @param object 数组或集合或JSON数组字符串
* @param jsonConfig JSON选项
* @throws JSONException 非数组或集合
* @since 4.6.5
*/
public JSONArray(final Object object, final JSONConfig jsonConfig) throws JSONException {
this(object, jsonConfig, null);
}
/**
* 从对象构造<br>
* 支持以下类型的参数:
*
* <pre>
* 1. 数组
* 2. {@link Iterable}对象
* 3. JSON数组字符串
* </pre>
*
* @param object 数组或集合或JSON数组字符串
* @param jsonConfig JSON选项
* @param predicate 键值对过滤编辑器,可以通过实现此接口,完成解析前对值的过滤和修改操作,{@code null}表示不过滤,{@link Predicate#test(Object)}为{@code true}保留
* @throws JSONException 非数组或集合
* @since 5.8.0
*/
public JSONArray(final Object object, final JSONConfig jsonConfig, final Predicate<MutableEntry<Object, Object>> predicate) throws JSONException {
this(DEFAULT_CAPACITY, jsonConfig);
JSONArrayMapper.of(object, predicate).mapTo(this);
}
// endregion
@@ -173,54 +103,21 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
return this.config;
}
/**
* 设置转为字符串时的日期格式默认为时间戳null值
*
* @param format 格式null表示使用时间戳
* @return this
* @since 4.1.19
*/
public JSONArray setDateFormat(final String format) {
this.config.setDateFormat(format);
return this;
}
/**
* JSONArray转为以{@code separator}为分界符的字符串
*
* @param separator 分界符
* @return a string.
* @throws JSONException If the array contains an invalid number.
*/
public String join(final String separator) throws JSONException {
return StrJoiner.of(separator)
.append(this, InternalJSONUtil::valueToString).toString();
}
@Override
public Object get(final int index) {
Object value = this.rawList.get(index);
if(value instanceof JSONPrimitive){
value = ((JSONPrimitive) value).getValue();
}
return value;
public JSON get(final int index) {
return this.raw.get(index);
}
@Override
public Object getObj(final Integer index, final Object defaultValue) {
return (index < 0 || index >= this.size()) ? defaultValue : this.rawList.get(index);
}
/**
* Append an object value. This increases the array's length by one. <br>
* 加入元素,数组长度+1等同于 {@link JSONArray#add(Object)}
*
* @param value 值,可以是: Boolean, Double, Integer, JSONArray, JSONObject, Long, or String, or the JSONNull.NULL。
* @return this.
* @see #set(Object)
*/
public JSONArray put(final Object value) {
return set(value);
final Object value;
final JSON json = get(index);
if(json instanceof JSONPrimitive){
value = ((JSONPrimitive) json).getValue();
}else {
value = json;
}
return ObjUtil.defaultIfNull(value, defaultValue);
}
/**
@@ -232,21 +129,7 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
* @since 5.2.5
*/
public JSONArray set(final Object value) {
this.add(value);
return this;
}
/**
* 加入或者替换JSONArray中指定Index的值如果index大于JSONArray的长度将在指定index设置值之前的位置填充JSONNull.Null
*
* @param index 位置
* @param value 值对象. 可以是以下类型: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or the JSONNull.NULL.
* @return this.
* @throws JSONException index &lt; 0 或者非有限的数字
* @see #set(int, Object)
*/
public JSONArray put(final int index, final Object value) throws JSONException {
this.set(index, value);
this.add(config.getConverter().convert(JSON.class, value));
return this;
}
@@ -268,36 +151,10 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
return jo;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((rawList == null) ? 0 : rawList.hashCode());
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final JSONArray other = (JSONArray) obj;
if (rawList == null) {
return other.rawList == null;
} else {
return rawList.equals(other.rawList);
}
}
@Override
public Iterator<Object> iterator() {
return rawList.iterator();
public Iterator<JSON> iterator() {
return raw.iterator();
}
/**
@@ -309,7 +166,7 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
* @param type JSON类型
*/
public <T extends JSON> Iterable<T> jsonIter(final Class<T> type) {
final Iterator<Object> iterator = iterator();
final Iterator<JSON> iterator = iterator();
return () -> new Iterator<T>() {
@Override
public boolean hasNext() {
@@ -327,26 +184,6 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
};
}
@Override
public int size() {
return rawList.size();
}
@Override
public boolean isEmpty() {
return rawList.isEmpty();
}
@Override
public boolean contains(final Object o) {
return rawList.contains(o);
}
@Override
public Object[] toArray() {
return rawList.toArray();
}
@Override
@SuppressWarnings({"unchecked"})
public <T> T[] toArray(final T[] a) {
@@ -354,78 +191,29 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
}
@Override
public boolean add(final Object e) {
return add(e, null);
}
/**
* 增加元素
*
* @param e 元素对象自动根据对象类型转换为JSON中的对象
* @param predicate 键值对过滤编辑器,可以通过实现此接口,完成解析前对值的过滤和修改操作,{@code null}表示不过滤,{@link Predicate#test(Object)}为{@code true}保留
* @return 是否加入成功
*/
public boolean add(final Object e, final Predicate<Mutable<Object>> predicate) {
return addRaw(valueMapper.map(e), predicate);
}
@Override
public Object remove(final int index) {
return index >= 0 && index < this.size() ? this.rawList.remove(index) : null;
}
@Override
public boolean remove(final Object o) {
return rawList.remove(o);
}
@SuppressWarnings({"NullableProblems", "SlowListContainsAll"})
@Override
public boolean containsAll(final Collection<?> c) {
return rawList.containsAll(c);
}
@Override
public boolean addAll(final Collection<?> c) {
public boolean addAll(final int index, final Collection<? extends JSON> c) {
if (CollUtil.isEmpty(c)) {
return false;
}
for (final Object obj : c) {
this.add(obj);
}
return true;
}
@Override
public boolean addAll(final int index, final Collection<?> c) {
if (CollUtil.isEmpty(c)) {
return false;
}
final ArrayList<Object> list = new ArrayList<>(c.size());
for (final Object object : c) {
if (null == object && config.isIgnoreNullValue()) {
final List<JSON> list = new ArrayList<>(c.size());
for (final JSON json : c) {
if (null == json && config.isIgnoreNullValue()) {
continue;
}
this.add(index);
list.add(valueMapper.map(object));
list.add(json);
}
return rawList.addAll(index, list);
return raw.addAll(index, list);
}
@Override
public boolean removeAll(final Collection<?> c) {
return this.rawList.removeAll(c);
}
@Override
public boolean retainAll(final Collection<?> c) {
return this.rawList.retainAll(c);
}
@Override
public void clear() {
this.rawList.clear();
/**
* 加入或者替换JSONArray中指定Index的值如果index大于JSONArray的长度将在指定index设置值之前的位置填充JSONNull.Null
*
* @param index 位置
* @param element 值对象. 可以是以下类型: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or the JSONNull.NULL.
* @return 替换的值,即之前的值
*/
public JSON setValue(final int index, final Object element) {
return set(index, config.getConverter().convert(JSON.class, element));
}
/**
@@ -436,29 +224,7 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
* @return 替换的值,即之前的值
*/
@Override
public Object set(final int index, final Object element) {
return set(index, element, null);
}
/**
* 加入或者替换JSONArray中指定Index的值如果index大于JSONArray的长度将在指定index设置值之前的位置填充JSONNull.Null
*
* @param index 位置
* @param element 值对象. 可以是以下类型: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or the JSONNull.NULL.
* @param filter 过滤器可以修改值keyindex无法修改{@link Predicate#test(Object)}为{@code true}保留null表示全部保留。
* @return 替换的值,即之前的值
* @since 5.8.0
*/
public Object set(final int index, Object element, final Predicate<MutableEntry<Integer, Object>> filter) {
// 添加前置过滤通过MutablePair实现过滤、修改键值对等
if (null != filter) {
final MutableEntry<Integer, Object> pair = new MutableEntry<>(index, element);
if (filter.test(pair)) {
// 使用修改后的值
element = pair.getValue();
}
}
public JSON set(final int index, final JSON element) {
// 越界则追加到指定位置
if (index >= size()) {
add(index, element);
@@ -467,11 +233,11 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
if (null == element && config.isIgnoreNullValue()) {
return null;
}
return this.rawList.set(index, valueMapper.map(element));
return this.raw.set(index, element);
}
@Override
public void add(int index, final Object element) {
public void add(int index, final JSON element) {
if (null == element && config.isIgnoreNullValue()) {
return;
}
@@ -479,7 +245,7 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
if (index < 0) {
index = 0;
}
this.rawList.add(index, valueMapper.map(element));
this.raw.add(index, element);
} else {
// issue#3286, 如果用户指定的index太大容易造成Java heap space错误。
if (!config.isIgnoreNullValue()) {
@@ -495,31 +261,6 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
}
@Override
public int indexOf(final Object o) {
return this.rawList.indexOf(o);
}
@Override
public int lastIndexOf(final Object o) {
return this.rawList.lastIndexOf(o);
}
@Override
public ListIterator<Object> listIterator() {
return this.rawList.listIterator();
}
@Override
public ListIterator<Object> listIterator(final int index) {
return this.rawList.listIterator(index);
}
@Override
public List<Object> subList(final int fromIndex, final int toIndex) {
return this.rawList.subList(fromIndex, toIndex);
}
/**
* 转为Bean数组
*
@@ -569,45 +310,15 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
@Override
public void write(final JSONWriter writer) throws JSONException {
final JSONWriter copyWriter = writer.copyOfSub();
copyWriter.beginArray();
CollUtil.forEach(this, (value, index) -> copyWriter.writeField(new MutableEntry<>(index, value)));
copyWriter.end();
writer.beginArray();
CollUtil.forEach(this, (index, value) -> writer.writeField(new MutableEntry<>(index, value)));
writer.end();
}
@Override
public Object clone() throws CloneNotSupportedException {
final JSONArray clone = (JSONArray) super.clone();
clone.config = this.config;
clone.valueMapper = this.valueMapper;
clone.rawList = ObjUtil.clone(this.rawList);
return clone;
}
/**
* 原始添加,添加的对象不做任何处理
*
* @param obj 添加的对象
* @param predicate 键值对过滤编辑器,可以通过实现此接口,完成解析前对值的过滤和修改操作,{@code null}表示不过滤,{@link Predicate#test(Object)}为{@code true}保留
* @return 是否加入成功
* @since 5.8.0
*/
protected boolean addRaw(Object obj, final Predicate<Mutable<Object>> predicate) {
// 添加前置过滤通过MutablePair实现过滤、修改键值对等
if (null != predicate) {
final Mutable<Object> mutable = new MutableObj<>(obj);
if (predicate.test(mutable)) {
// 使用修改后的值
obj = mutable.get();
} else {
// 键值对被过滤
return false;
}
}
if (null == obj && config.isIgnoreNullValue()) {
// 忽略空则不添加
return false;
}
return this.rawList.add(obj);
}
}

View File

@@ -87,7 +87,7 @@ public interface JSONGetter<K> extends TypeGetter<K> {
if (object instanceof JSON) {
return (JSONArray) object;
}
return new JSONArray(object, config());
return JSONUtil.parseArray(object, config());
}
/**

View File

@@ -25,7 +25,6 @@ import org.dromara.hutool.core.map.MapUtil;
import org.dromara.hutool.core.map.MapWrapper;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.core.util.ObjUtil;
import org.dromara.hutool.json.mapper.JSONValueMapper;
import org.dromara.hutool.json.writer.JSONWriter;
import java.util.Arrays;
@@ -53,10 +52,6 @@ public class JSONObject extends MapWrapper<String, JSON> implements JSON, JSONGe
* 配置项
*/
private final JSONConfig config;
/**
* 对象转换和包装用于将Java对象和值转换为JSON值
*/
private final JSONValueMapper valueMapper;
/**
* 构造,初始容量为 {@link #DEFAULT_CAPACITY}KEY有序
@@ -84,7 +79,6 @@ public class JSONObject extends MapWrapper<String, JSON> implements JSON, JSONGe
public JSONObject(final int capacity, final JSONConfig config) {
super(InternalJSONUtil.createRawMap(capacity, config));
this.config = ObjUtil.defaultIfNull(config, JSONConfig::of);
this.valueMapper = JSONValueMapper.of(this.config);
}
@Override
@@ -94,10 +88,9 @@ public class JSONObject extends MapWrapper<String, JSON> implements JSON, JSONGe
@Override
public void write(final JSONWriter writer) throws JSONException {
final JSONWriter jsonWriter = writer.copyOfSub();
jsonWriter.beginObj();
this.forEach((key, value) -> jsonWriter.writeField(new MutableEntry<>(key, value)));
jsonWriter.end();
writer.beginObj();
this.forEach((key, value) -> writer.writeField(new MutableEntry<>(key, value)));
writer.end();
}
// region ----- get
@@ -225,7 +218,7 @@ public class JSONObject extends MapWrapper<String, JSON> implements JSON, JSONGe
* @throws JSONException 值是无穷数字抛出此异常
*/
public JSONObject set(final String key, final Object value) throws JSONException {
this.put(key, valueMapper.map(value));
this.put(key, this.config.getConverter().convert(JSON.class, value));
return this;
}

View File

@@ -23,8 +23,7 @@ import org.dromara.hutool.core.lang.mutable.MutableEntry;
import org.dromara.hutool.core.reflect.TypeReference;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.core.util.ObjUtil;
import org.dromara.hutool.json.convert.JSONConverter;
import org.dromara.hutool.json.mapper.JSONObjectMapper;
import org.dromara.hutool.json.mapper.JSONValueMapper;
import org.dromara.hutool.json.writer.JSONWriter;
import org.dromara.hutool.json.writer.ValueWriter;
import org.dromara.hutool.json.writer.ValueWriterManager;
@@ -46,6 +45,7 @@ import java.util.function.Predicate;
public class JSONUtil {
// region ----- of
/**
* 创建JSONObject
*
@@ -88,6 +88,7 @@ public class JSONUtil {
// endregion
// region ----- parse
/**
* JSON字符串转JSONObject对象<br>
* 此方法会忽略空值但是对JSON字符串不影响
@@ -99,18 +100,6 @@ public class JSONUtil {
return parseObj(obj, JSONConfig.of(), null);
}
/**
* JSON字符串转JSONObject对象
*
* @param obj Bean对象或者Map
* @param ignoreNullValue 是否忽略空值如果source为JSON字符串不忽略空值
* @return JSONObject
* @since 3.0.9
*/
public static JSONObject parseObj(final Object obj, final boolean ignoreNullValue) {
return parseObj(obj, JSONConfig.of().setIgnoreNullValue(ignoreNullValue));
}
/**
* JSON字符串转JSONObject对象<br>
* 此方法会忽略空值但是对JSON字符串不影响
@@ -133,9 +122,7 @@ public class JSONUtil {
* @return JSONObject
*/
public static JSONObject parseObj(final Object obj, final JSONConfig config, final Predicate<MutableEntry<Object, Object>> predicate) {
final JSONObject jsonObject = new JSONObject(config);
JSONObjectMapper.of(obj, predicate).mapTo(jsonObject);
return jsonObject;
return (JSONObject) parse(obj, config, predicate);
}
/**
@@ -146,7 +133,7 @@ public class JSONUtil {
* @since 3.0.8
*/
public static JSONArray parseArray(final Object arrayOrCollection) {
return new JSONArray(arrayOrCollection);
return parseArray(arrayOrCollection, null);
}
/**
@@ -158,7 +145,20 @@ public class JSONUtil {
* @since 5.3.1
*/
public static JSONArray parseArray(final Object arrayOrCollection, final JSONConfig config) {
return new JSONArray(arrayOrCollection, config);
return parseArray(arrayOrCollection, config, null);
}
/**
* JSON字符串转JSONArray
*
* @param arrayOrCollection 数组或集合对象
* @param config JSON配置
* @param predicate index和值对过滤编辑器可以通过实现此接口完成解析前对键值对的过滤和修改操作{@link Predicate#test(Object)}为{@code true}保留
* @return JSONArray
* @since 5.3.1
*/
public static JSONArray parseArray(final Object arrayOrCollection, final JSONConfig config, final Predicate<MutableEntry<Object, Object>> predicate) {
return (JSONArray) parse(arrayOrCollection, config, predicate);
}
/**
@@ -186,15 +186,34 @@ public class JSONUtil {
* <li>Bean对象转为JSONObject</li>
* </ul>
*
* @param obj 对象
* @param config JSON配置{@code null}使用默认配置
* @param obj 对象
* @param config JSON配置{@code null}使用默认配置
* @return JSONJSONObject or JSONArray
*/
public static JSON parse(final Object obj, final JSONConfig config) {
if (null == config) {
return JSONConverter.INSTANCE.toJSON(obj);
return parse(obj, config, null);
}
/**
* 转换对象为JSON如果用户不配置JSONConfig则JSON的有序与否与传入对象有关。<br>
* 支持的对象:
* <ul>
* <li>String: 转换为相应的对象</li>
* <li>Array、Iterable、Iterator转换为JSONArray</li>
* <li>Bean对象转为JSONObject</li>
* </ul>
*
* @param obj 对象
* @param config JSON配置{@code null}使用默认配置
* @param predicate 键值对过滤编辑器,可以通过实现此接口,完成解析前对键值对的过滤和修改操作,{@link Predicate#test(Object)}为{@code true}保留
* @return JSONJSONObject or JSONArray
*/
public static JSON parse(final Object obj, final JSONConfig config, final Predicate<MutableEntry<Object, Object>> predicate) {
final JSONValueMapper jsonValueMapper = JSONValueMapper.of(config, predicate);
if (obj instanceof CharSequence) {
return jsonValueMapper.map((CharSequence) obj);
}
return JSONConverter.of(config).toJSON(obj);
return jsonValueMapper.map(obj);
}
/**
@@ -219,7 +238,7 @@ public class JSONUtil {
* @throws IORuntimeException IO异常
*/
public static JSON readJSON(final File file, final Charset charset) throws IORuntimeException {
return (JSON) FileUtil.read(file, charset, JSONUtil::parse);
return FileUtil.read(file, charset, JSONUtil::parse);
}
/**

View File

@@ -16,14 +16,11 @@
package org.dromara.hutool.json.convert;
import org.dromara.hutool.core.array.ArrayUtil;
import org.dromara.hutool.core.bean.BeanUtil;
import org.dromara.hutool.core.bean.copier.BeanCopier;
import org.dromara.hutool.core.convert.*;
import org.dromara.hutool.core.convert.impl.DateConverter;
import org.dromara.hutool.core.convert.impl.TemporalAccessorConverter;
import org.dromara.hutool.core.lang.Opt;
import org.dromara.hutool.core.map.MapWrapper;
import org.dromara.hutool.core.reflect.ConstructorUtil;
import org.dromara.hutool.core.reflect.TypeReference;
import org.dromara.hutool.core.reflect.TypeUtil;
@@ -31,19 +28,16 @@ import org.dromara.hutool.core.reflect.kotlin.KClassUtil;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.core.util.ObjUtil;
import org.dromara.hutool.json.*;
import org.dromara.hutool.json.mapper.JSONValueMapper;
import org.dromara.hutool.json.reader.JSONParser;
import org.dromara.hutool.json.reader.JSONTokener;
import org.dromara.hutool.json.serializer.JSONDeserializer;
import org.dromara.hutool.json.serializer.JSONSerializer;
import org.dromara.hutool.json.serializer.SerializerManager;
import org.dromara.hutool.json.serializer.SimpleJSONContext;
import java.io.Serializable;
import java.lang.reflect.Type;
import java.time.temporal.TemporalAccessor;
import java.util.Date;
import java.util.Iterator;
import java.util.Optional;
/**
* JSON转换器实现Object对象转换为{@link JSON},支持的对象:
@@ -139,47 +133,12 @@ public class JSONConverter implements Converter, Serializable {
* @return 转换后的对象
* @throws JSONException 转换异常
*/
@SuppressWarnings("unchecked")
public JSON toJSON(Object obj) throws JSONException {
public JSON toJSON(final Object obj) throws JSONException {
if (null == obj) {
return null;
}
if (obj instanceof Optional) {
obj = ((Optional<?>) obj).orElse(null);
} else if (obj instanceof Opt) {
obj = ((Opt<?>) obj).getOrNull();
}
if (obj instanceof JSON) {
return (JSON) obj;
}
// 自定义序列化
final JSONSerializer<Object> serializer =
(JSONSerializer<Object>) SerializerManager.getInstance().getSerializer(obj);
if (null != serializer) {
return serializer.serialize(obj, new SimpleJSONContext(null, this.config));
}
if (obj instanceof Number || obj instanceof Boolean) {
// RFC8259规范的原始类型数据
return new JSONPrimitive(obj, config);
}
final JSON json;
if (obj instanceof CharSequence) {
return toJSON((CharSequence) obj);
} else if (obj instanceof MapWrapper) {
// MapWrapper实现了Iterable会被当作JSONArray此处做修正
json = JSONUtil.parseObj(obj, config);
} else if (obj instanceof Iterable || obj instanceof Iterator || ArrayUtil.isArray(obj)) {// 列表
json = JSONUtil.parseArray(obj, config);
} else {// 对象
json = JSONUtil.parseObj(obj, config);
}
return json;
return JSONValueMapper.of(config, null).map(obj);
}
/**
@@ -231,7 +190,7 @@ public class JSONConverter implements Converter, Serializable {
// 当目标类型不确定时返回原JSON
final Class<T> rawType = (Class<T>) TypeUtil.getClass(targetType);
if (null == rawType) {
if (null == rawType || rawType.isInstance(json)) {
return (T) json;
//throw new JSONException("Can not get class from type: {}", targetType);
}

View File

@@ -30,6 +30,7 @@ import org.dromara.hutool.json.jwt.signers.JWTSigner;
import org.dromara.hutool.json.jwt.signers.JWTSignerUtil;
import org.dromara.hutool.json.jwt.signers.NoneJWTSigner;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.security.Key;
import java.security.KeyPair;
@@ -299,7 +300,7 @@ public class JWT implements RegisteredPayload<JWT> {
* @throws ValidateException 传入的类型不匹配payload类型
* @since 6.0.0
*/
public <T> T getPayload(final String propertyName, final Class<T> propertyType) {
public <T> T getPayload(final String propertyName, final Type propertyType) {
return getPayload().getClaimsJson().get(propertyName, propertyType);
}

View File

@@ -20,15 +20,11 @@ import org.dromara.hutool.core.array.ArrayUtil;
import org.dromara.hutool.core.collection.iter.ArrayIter;
import org.dromara.hutool.core.io.IoUtil;
import org.dromara.hutool.core.lang.mutable.MutableEntry;
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.JSONTokener;
import org.dromara.hutool.json.serializer.JSONSerializer;
import org.dromara.hutool.json.serializer.SerializerManager;
import org.dromara.hutool.json.serializer.SimpleJSONContext;
import java.io.InputStream;
import java.io.Reader;
@@ -50,7 +46,7 @@ import java.util.function.Predicate;
* @author looly
* @since 6.0.0
*/
public class JSONArrayMapper {
class JSONArrayMapper {
/**
* 创建ArrayMapper
*
@@ -88,20 +84,10 @@ public class JSONArrayMapper {
return;
}
// 自定义序列化
final JSONSerializer<Object> serializer = SerializerManager.getInstance().getSerializer(source.getClass());
if (null != serializer) {
serializer.serialize(source, new SimpleJSONContext(jsonArray));
return;
}
if (source instanceof JSONTokener) {
mapFromTokener((JSONTokener) source, JSONConfig.of(), jsonArray);
}if (source instanceof JSONParser) {
((JSONParser)source).parseTo(jsonArray);
} else if (source instanceof CharSequence) {
// JSON字符串
mapFromStr((CharSequence) source, jsonArray);
} else if (source instanceof Reader) {
mapFromTokener(new JSONTokener((Reader) source), jsonArray.config(), jsonArray);
} else if (source instanceof InputStream) {
@@ -114,7 +100,7 @@ public class JSONArrayMapper {
// https://github.com/dromara/hutool/issues/2369
// 非标准的二进制流,则按照普通数组对待
for (final byte b : bytesSource) {
jsonArray.add(b);
jsonArray.set(b);
}
}
} else {
@@ -143,28 +129,16 @@ public class JSONArrayMapper {
if (predicate.test(entry)) {
// 使用修改后的键值对
next = entry.getValue();
jsonArray.add(next);
jsonArray.set(next);
}
}else {
jsonArray.add(next);
jsonArray.set(next);
}
}
}
}
}
/**
* 初始化
*
* @param source JSON字符串
* @param jsonArray {@link JSONArray}
*/
private void mapFromStr(final CharSequence source, final JSONArray jsonArray) {
if (null != source) {
mapFromTokener(new JSONTokener(StrUtil.trim(source)), jsonArray.config(), jsonArray);
}
}
/**
* 初始化
*

View File

@@ -27,11 +27,6 @@ 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.JSONTokener;
import org.dromara.hutool.json.serializer.JSONSerializer;
import org.dromara.hutool.json.serializer.SerializerManager;
import org.dromara.hutool.json.serializer.SimpleJSONContext;
import org.dromara.hutool.json.xml.JSONXMLParser;
import org.dromara.hutool.json.xml.ParseConfig;
import java.io.InputStream;
import java.io.Reader;
@@ -55,9 +50,8 @@ import java.util.function.Predicate;
* </ul>
*
* @author looly
* @since 5.8.0
*/
public class JSONObjectMapper {
class JSONObjectMapper {
/**
* 创建ObjectMapper
@@ -96,13 +90,6 @@ public class JSONObjectMapper {
return;
}
// 自定义序列化
final JSONSerializer<Object> serializer = SerializerManager.getInstance().getSerializer(source.getClass());
if (null != serializer) {
serializer.serialize(source, new SimpleJSONContext(jsonObject));
return;
}
if (source instanceof JSONArray) {
// 不支持集合类型转换为JSONObject
throw new JSONException("Unsupported type [{}] to JSONObject!", source.getClass());
@@ -122,9 +109,6 @@ public class JSONObjectMapper {
} else if (source instanceof Map.Entry) {
final Map.Entry entry = (Map.Entry) source;
jsonObject.set(ConvertUtil.toStr(entry.getKey()), entry.getValue());
} else if (source instanceof CharSequence) {
// 可能为JSON字符串
mapFromStr((CharSequence) source, jsonObject);
} else if (source instanceof Reader) {
mapFromTokener(new JSONTokener((Reader) source), jsonObject.config(), jsonObject);
} else if (source instanceof InputStream) {
@@ -165,23 +149,6 @@ public class JSONObjectMapper {
}
}
/**
* 从字符串转换
*
* @param source JSON字符串
* @param jsonObject {@link JSONObject}
*/
private void mapFromStr(final CharSequence source, final JSONObject jsonObject) {
final String jsonStr = StrUtil.trim(source);
if (StrUtil.startWith(jsonStr, '<')) {
// 可能为XML
//JSONXMLUtil.toJSONObject(jsonStr, jsonObject, ParseConfig.of());
JSONXMLParser.of(ParseConfig.of(), this.predicate).parseJSONObject(jsonStr, jsonObject);
return;
}
mapFromTokener(new JSONTokener(source), jsonObject.config(), jsonObject);
}
/**
* 从{@link JSONTokener}转换
*

View File

@@ -18,10 +18,23 @@ package org.dromara.hutool.json.mapper;
import org.dromara.hutool.core.array.ArrayUtil;
import org.dromara.hutool.core.exception.ExceptionUtil;
import org.dromara.hutool.core.lang.Opt;
import org.dromara.hutool.core.lang.mutable.MutableEntry;
import org.dromara.hutool.core.map.MapWrapper;
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.JSONTokener;
import org.dromara.hutool.json.serializer.JSONSerializer;
import org.dromara.hutool.json.serializer.SerializerManager;
import org.dromara.hutool.json.serializer.SimpleJSONContext;
import org.dromara.hutool.json.writer.ValueWriterManager;
import org.dromara.hutool.json.xml.JSONXMLParser;
import org.dromara.hutool.json.xml.ParseConfig;
import java.io.Serializable;
import java.util.Optional;
import java.util.function.Predicate;
/**
* 对象和JSON值映射器用于转换对象为JSON对象中的值<br>
@@ -45,22 +58,45 @@ public class JSONValueMapper implements Serializable {
/**
* 创建ObjectMapper
*
* @param jsonConfig 来源对象
* @param jsonConfig 来源对象
* @param predicate 键值对过滤编辑器,可以通过实现此接口,完成解析前对键值对的过滤和修改操作,{@link Predicate#test(Object)}为{@code true}保留
* @return ObjectMapper
*/
public static JSONValueMapper of(final JSONConfig jsonConfig) {
return new JSONValueMapper(jsonConfig);
public static JSONValueMapper of(final JSONConfig jsonConfig, final Predicate<MutableEntry<Object, Object>> predicate) {
return new JSONValueMapper(jsonConfig, predicate);
}
private final JSONConfig jsonConfig;
private final Predicate<MutableEntry<Object, Object>> predicate;
/**
* 构造
*
* @param jsonConfig JSON配置
* @param jsonConfig JSON配置
* @param predicate 键值对过滤编辑器,可以通过实现此接口,完成解析前对键值对的过滤和修改操作,{@link Predicate#test(Object)}为{@code true}保留
*/
public JSONValueMapper(final JSONConfig jsonConfig) {
public JSONValueMapper(final JSONConfig jsonConfig, final Predicate<MutableEntry<Object, Object>> predicate) {
this.jsonConfig = jsonConfig;
this.predicate = predicate;
}
/**
* 解析JSON字符串或XML字符串为JSON结构
*
* @param source JSON字符串或XML字符串
* @return JSON对象
*/
public JSON map(final CharSequence source) {
final String jsonStr = StrUtil.trim(source);
if (StrUtil.startWith(jsonStr, '<')) {
// 可能为XML
final JSONObject jsonObject = new JSONObject(jsonConfig);
JSONXMLParser.of(ParseConfig.of(), this.predicate).parseJSONObject(jsonStr, jsonObject);
return jsonObject;
}
return JSONParser.of(new JSONTokener(source), jsonConfig)
.setPredicate(this.predicate)
.parse();
}
/**
@@ -74,38 +110,52 @@ public class JSONValueMapper implements Serializable {
* <li>其它 =》 尝试包装为JSONObject否则返回{@code null}</li>
* </ul>
*
* @param object 被映射的对象
* @param obj 被映射的对象
* @return 映射后的值null表示此值需被忽略
*/
public JSON map(final Object object) {
if(null == object || object instanceof JSON){
return (JSON) object;
public JSON map(Object obj) {
if (null == obj) {
return null;
}
if(null != ValueWriterManager.getInstance().get(object)){
return new JSONPrimitive(object, jsonConfig);
if (obj instanceof Optional) {
obj = ((Optional<?>) obj).orElse(null);
} else if (obj instanceof Opt) {
obj = ((Opt<?>) obj).getOrNull();
}
// if (object instanceof CharSequence
// || ObjUtil.isBasicType(object)) {
// return new JSONPrimitive(object, jsonConfig);
// }
if (obj instanceof JSON) {
return (JSON) obj;
}
// 自定义序列化
final JSONSerializer<Object> serializer = SerializerManager.getInstance().getSerializer(obj);
if (null != serializer) {
return serializer.serialize(obj, new SimpleJSONContext(null, this.jsonConfig));
}
// 原始类型
if (null != ValueWriterManager.getInstance().get(obj)) {
return new JSONPrimitive(obj, jsonConfig);
}
// 特定对象转换
try {
// JSONArray
if (object instanceof Iterable || ArrayUtil.isArray(object)) {
if (// MapWrapper实现了Iterable会被当作JSONArray此处做修正
!(obj instanceof MapWrapper) &&
(obj instanceof Iterable || ArrayUtil.isArray(obj))) {
final JSONArray jsonArray = new JSONArray(jsonConfig);
JSONArrayMapper.of(object, null).mapTo(jsonArray);
JSONArrayMapper.of(obj, predicate).mapTo(jsonArray);
return jsonArray;
}
// 默认按照JSONObject对待
final JSONObject jsonObject = new JSONObject(jsonConfig);
JSONObjectMapper.of(object, null).mapTo(jsonObject);
JSONObjectMapper.of(obj, predicate).mapTo(jsonObject);
return jsonObject;
} catch (final Exception exception) {
if(jsonConfig.isIgnoreError()){
if (jsonConfig.isIgnoreError()) {
return null;
}
throw ExceptionUtil.wrap(exception, JSONException.class);

View File

@@ -232,13 +232,13 @@ public class JSONParser {
return;
} else {
// ,value or value
Object value = nextJSON(CharUtil.COMMA == c ? tokener.nextClean() : c);
JSON value = nextJSON(CharUtil.COMMA == c ? tokener.nextClean() : c);
if (null != predicate) {
// 使用过滤器
final MutableEntry<Object, Object> entry = MutableEntry.of(jsonArray.size(), value);
if (predicate.test(entry)) {
// 使用修改后的键值对
value = entry.getValue();
value = (JSON) entry.getValue();
jsonArray.add(value);
}
} else {

View File

@@ -161,11 +161,11 @@ public class SerializerManager {
* @param bean 对象
* @return JSONSerializer
*/
@SuppressWarnings({"rawtypes"})
public JSONSerializer<?> getSerializer(final Object bean) {
for (final MatcherJSONSerializer serializer : this.serializerSet) {
@SuppressWarnings({"unchecked"})
public JSONSerializer<Object> getSerializer(final Object bean) {
for (final MatcherJSONSerializer<?> serializer : this.serializerSet) {
if (serializer.match(bean, null)) {
return serializer;
return (JSONSerializer<Object>) serializer;
}
}
return null;

View File

@@ -121,16 +121,6 @@ public class JSONWriter implements Appendable, Flushable, Closeable {
return this.config;
}
/**
* 复制当前对象,用于修改配置后写出
* @return JSONWriter
*/
@SuppressWarnings("resource")
public JSONWriter copyOfSub() {
return new JSONWriter(this.appendable, this.indentFactor, this.indent + indentFactor, this.config)
.setPredicate(this.predicate);
}
/**
* JSONObject写出开始默认写出"{"
*
@@ -141,6 +131,7 @@ public class JSONWriter implements Appendable, Flushable, Closeable {
append(CharUtil.DELIM_START);
arrayMode = false;
needSeparator = false;
indent += indentFactor;
return this;
}
@@ -154,6 +145,7 @@ public class JSONWriter implements Appendable, Flushable, Closeable {
append(CharUtil.BRACKET_START);
arrayMode = true;
needSeparator = false;
indent += indentFactor;
return this;
}
@@ -164,6 +156,8 @@ public class JSONWriter implements Appendable, Flushable, Closeable {
*/
@SuppressWarnings("resource")
public JSONWriter end() {
// 结束子缩进
indent -= indentFactor;
// 换行缩进
writeLF().writeSpace(indent);
append(arrayMode ? CharUtil.BRACKET_END : CharUtil.DELIM_END);
@@ -215,7 +209,7 @@ public class JSONWriter implements Appendable, Flushable, Closeable {
append(CharUtil.COMMA);
}
// 换行缩进
writeLF().writeSpace(indentFactor + indent);
writeLF().writeSpace(indent);
return writeRaw(InternalJSONUtil.quote(key));
}
@@ -346,7 +340,7 @@ public class JSONWriter implements Appendable, Flushable, Closeable {
}
// 换行缩进
//noinspection resource
writeLF().writeSpace(indentFactor + indent);
writeLF().writeSpace(indent);
} else {
//noinspection resource
append(CharUtil.COLON).writeSpace(1);

View File

@@ -100,7 +100,7 @@ public class ValueWriterManager {
private static void registerDefault() {
final ValueWriterManager manager = SingletonHolder.INSTANCE;
// JDK对象最后判断
manager.register(JdkValueWriter.INSTANCE);
// manager.register(JdkValueWriter.INSTANCE);
manager.register(NumberValueWriter.INSTANCE);
manager.register(DateValueWriter.INSTANCE);
manager.register(BooleanValueWriter.INSTANCE);

View File

@@ -23,6 +23,7 @@ import org.dromara.hutool.core.text.escape.EscapeUtil;
import org.dromara.hutool.json.JSONArray;
import org.dromara.hutool.json.JSONException;
import org.dromara.hutool.json.JSONObject;
import org.dromara.hutool.json.JSONUtil;
/**
* JSON转XML字符串工具
@@ -78,7 +79,7 @@ public class JSONXMLSerializer {
// Loop thru the keys.
((JSONObject) object).forEach((key, value) -> {
if (ArrayUtil.isArray(value)) {
value = new JSONArray(value);
value = JSONUtil.parseArray(value);
}
// Emit content in body
@@ -119,7 +120,7 @@ public class JSONXMLSerializer {
}
if (ArrayUtil.isArray(object)) {
object = new JSONArray(object);
object = JSONUtil.parseArray(object);
}
if (object instanceof JSONArray) {