diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanUtil.java index 4abd24302..617a574e5 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanUtil.java @@ -454,7 +454,6 @@ public class BeanUtil { * @param ignoreProperties 不拷贝的的属性列表 * @return 目标对象 */ - @SuppressWarnings("unchecked") public static T copyProperties(final Object source, final Class tClass, final String... ignoreProperties) { if (null == source) { return null; @@ -462,7 +461,7 @@ public class BeanUtil { if (RecordUtil.isRecord(tClass)) { // issue#I7EO3U // 转换record时,ignoreProperties无效 - return (T) RecordConverter.INSTANCE.convert(tClass, source); + return RecordConverter.INSTANCE.convert(tClass, source); } final T target = ConstructorUtil.newInstanceIfPossible(tClass); return copyProperties(source, target, CopyOptions.of().setIgnoreProperties(ignoreProperties)); diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/collection/CollUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/collection/CollUtil.java index 03fca5bf4..0e8ff029e 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/collection/CollUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/collection/CollUtil.java @@ -1955,7 +1955,7 @@ public class CollUtil { * @param consumer {@link SerBiConsumer} 遍历的每条数据处理器 * @since 5.4.7 */ - public static void forEach(final Iterable iterable, final SerBiConsumer consumer) { + public static void forEach(final Iterable iterable, final SerBiConsumer consumer) { if (iterable == null) { return; } @@ -1969,13 +1969,13 @@ public class CollUtil { * @param iterator {@link Iterator} * @param consumer {@link SerBiConsumer} 遍历的每条数据处理器 */ - public static void forEach(final Iterator iterator, final SerBiConsumer consumer) { + public static void forEach(final Iterator iterator, final SerBiConsumer consumer) { if (iterator == null) { return; } int index = 0; while (iterator.hasNext()) { - consumer.accept(iterator.next(), index); + consumer.accept(index, iterator.next()); index++; } } @@ -1987,13 +1987,13 @@ public class CollUtil { * @param enumeration {@link Enumeration} * @param consumer {@link SerBiConsumer} 遍历的每条数据处理器 */ - public static void forEach(final Enumeration enumeration, final SerBiConsumer consumer) { + public static void forEach(final Enumeration enumeration, final SerBiConsumer consumer) { if (enumeration == null) { return; } int index = 0; while (enumeration.hasMoreElements()) { - consumer.accept(enumeration.nextElement(), index); + consumer.accept(index, enumeration.nextElement()); index++; } } @@ -2007,13 +2007,13 @@ public class CollUtil { * @param map {@link Map} * @param kvConsumer {@link SerConsumer3} 遍历的每条数据处理器 */ - public static void forEach(final Map map, final SerConsumer3 kvConsumer) { + public static void forEach(final Map map, final SerConsumer3 kvConsumer) { if (map == null) { return; } int index = 0; for (final Entry entry : map.entrySet()) { - kvConsumer.accept(entry.getKey(), entry.getValue(), index); + kvConsumer.accept(index, entry.getKey(), entry.getValue()); index++; } } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/collection/ListWrapper.java b/hutool-core/src/main/java/org/dromara/hutool/core/collection/ListWrapper.java index 39fc4e5e2..118688fdb 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/collection/ListWrapper.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/collection/ListWrapper.java @@ -191,4 +191,21 @@ public class ListWrapper extends SimpleWrapper> implements List { public Stream parallelStream() { return raw.parallelStream(); } + + @Override + public int hashCode() { + return this.raw.hashCode(); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final ListWrapper that = (ListWrapper) obj; + return Objects.equals(raw, that.raw); + } } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/convert/ConvertUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/convert/ConvertUtil.java index 76b1c3a35..ba5d7cf24 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/convert/ConvertUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/convert/ConvertUtil.java @@ -561,10 +561,9 @@ public class ConvertUtil { * @param defaultValue 默认值 * @return Enum */ - @SuppressWarnings("unchecked") public static > E toEnum(final Class clazz, final Object value, final E defaultValue) { try { - return (E) EnumConverter.INSTANCE.convert(clazz, value); + return EnumConverter.INSTANCE.convert(clazz, value); } catch (final Exception ignore) { return defaultValue; } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/convert/Converter.java b/hutool-core/src/main/java/org/dromara/hutool/core/convert/Converter.java index 81f645e91..6cb8bffb5 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/convert/Converter.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/convert/Converter.java @@ -40,6 +40,21 @@ public interface Converter { */ Object convert(Type targetType, Object value) throws ConvertException; + /** + * 转换为指定类型
+ * 如果类型无法确定,将读取默认值的类型做为目标类型 + * + * @param 目标类型 + * @param targetType 目标类型 + * @param value 原始值,如果对象实现了此接口,则value为this + * @return 转换后的值 + * @throws ConvertException 转换无法正常完成或转换异常时抛出此异常 + */ + @SuppressWarnings("unchecked") + default T convert(final Class targetType, final Object value) throws ConvertException { + return (T) convert((Type) targetType, value); + } + /** * 转换值为指定类型,可选是否不抛异常转换
* 当转换失败时返回默认值 @@ -57,9 +72,10 @@ public interface Converter { /** * 返回原值的转换器,不做转换 + * * @return Converter */ - static Converter identity(){ + static Converter identity() { return (targetType, value) -> value; } } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/TupleConverter.java b/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/TupleConverter.java index 7a557e8c8..5d71013c1 100755 --- a/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/TupleConverter.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/TupleConverter.java @@ -37,7 +37,7 @@ public class TupleConverter implements Converter { @Override public Object convert(final Type targetType, final Object value) throws ConvertException { - final Object[] convert = (Object[]) ArrayConverter.INSTANCE.convert(Object[].class, value); + final Object[] convert = ArrayConverter.INSTANCE.convert(Object[].class, value); return Tuple.of(convert); } } diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/collection/CollUtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/collection/CollUtilTest.java index c18f284bb..44cd910d1 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/collection/CollUtilTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/collection/CollUtilTest.java @@ -321,7 +321,7 @@ public class CollUtilTest { final String[] result = new String[1]; final String a = "a"; - CollUtil.forEach(map, (key, value, index) -> { + CollUtil.forEach(map, (index, key, value) -> { if (a.equals(key)) { result[0] = value; } diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/convert/CompositeConverterTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/convert/CompositeConverterTest.java index f0f5fe23d..02ec9cbce 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/convert/CompositeConverterTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/convert/CompositeConverterTest.java @@ -32,7 +32,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; public class CompositeConverterTest { @Test void convertEmptyTest() { - final Object convert = CompositeConverter.getInstance().convert(EmptyBean.class, ""); + final EmptyBean convert = CompositeConverter.getInstance().convert(EmptyBean.class, ""); assertNotNull(convert); assertEquals(new EmptyBean(), convert); } @@ -45,13 +45,13 @@ public class CompositeConverterTest { final int a = 454553; final CompositeConverter compositeConverter = CompositeConverter.getInstance(); - CharSequence result = (CharSequence) compositeConverter.convert(CharSequence.class, a); + CharSequence result = compositeConverter.convert(CharSequence.class, a); assertEquals("454553", result); //此处做为示例自定义CharSequence转换,因为Hutool中已经提供CharSequence转换,请尽量不要替换 //替换可能引发关联转换异常(例如覆盖CharSequence转换会影响全局) compositeConverter.register(CharSequence.class, new CustomConverter()); - result = (CharSequence) compositeConverter.convert(CharSequence.class, a); + result = compositeConverter.convert(CharSequence.class, a); assertEquals("Custom: 454553", result); } diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/convert/ConvertTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/convert/ConvertTest.java index 19ec7c60f..f02b07c3a 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/convert/ConvertTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/convert/ConvertTest.java @@ -131,28 +131,28 @@ public class ConvertTest { final String a = " 34232"; final Integer aInteger = ConvertUtil.toInt(a); assertEquals(Integer.valueOf(34232), aInteger); - final int aInt = (int) CompositeConverter.getInstance().convert(int.class, a); + final int aInt = CompositeConverter.getInstance().convert(int.class, a); assertEquals(34232, aInt); // 带小数测试 final String b = " 34232.00"; final Integer bInteger = ConvertUtil.toInt(b); assertEquals(Integer.valueOf(34232), bInteger); - final int bInt = (int) CompositeConverter.getInstance().convert(int.class, b); + final int bInt = CompositeConverter.getInstance().convert(int.class, b); assertEquals(34232, bInt); // boolean测试 final boolean c = true; final Integer cInteger = ConvertUtil.toInt(c); assertEquals(Integer.valueOf(1), cInteger); - final int cInt = (int) CompositeConverter.getInstance().convert(int.class, c); + final int cInt = CompositeConverter.getInstance().convert(int.class, c); assertEquals(1, cInt); // boolean测试 final String d = "08"; final Integer dInteger = ConvertUtil.toInt(d); assertEquals(Integer.valueOf(8), dInteger); - final int dInt = (int) CompositeConverter.getInstance().convert(int.class, d); + final int dInt = CompositeConverter.getInstance().convert(int.class, d); assertEquals(8, dInt); } @@ -176,28 +176,28 @@ public class ConvertTest { final String a = " 342324545435435"; final Long aLong = ConvertUtil.toLong(a); assertEquals(Long.valueOf(342324545435435L), aLong); - final long aLong2 = (long) CompositeConverter.getInstance().convert(long.class, a); + final long aLong2 = CompositeConverter.getInstance().convert(long.class, a); assertEquals(342324545435435L, aLong2); // 带小数测试 final String b = " 342324545435435.245435435"; final Long bLong = ConvertUtil.toLong(b); assertEquals(Long.valueOf(342324545435435L), bLong); - final long bLong2 = (long) CompositeConverter.getInstance().convert(long.class, b); + final long bLong2 = CompositeConverter.getInstance().convert(long.class, b); assertEquals(342324545435435L, bLong2); // boolean测试 final boolean c = true; final Long cLong = ConvertUtil.toLong(c); assertEquals(Long.valueOf(1), cLong); - final long cLong2 = (long) CompositeConverter.getInstance().convert(long.class, c); + final long cLong2 = CompositeConverter.getInstance().convert(long.class, c); assertEquals(1, cLong2); // boolean测试 final String d = "08"; final Long dLong = ConvertUtil.toLong(d); assertEquals(Long.valueOf(8), dLong); - final long dLong2 = (long) CompositeConverter.getInstance().convert(long.class, d); + final long dLong2 = CompositeConverter.getInstance().convert(long.class, d); assertEquals(8, dLong2); } diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/convert/ConvertToArrayTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/convert/ConvertToArrayTest.java index bc4b99289..2b01d6667 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/convert/ConvertToArrayTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/convert/ConvertToArrayTest.java @@ -95,11 +95,11 @@ public class ConvertToArrayTest { //数组转数组测试 final int[] a = new int[]{1,2,3,4}; - final long[] result = (long[]) CompositeConverter.getInstance().convert(long[].class, a); + final long[] result = CompositeConverter.getInstance().convert(long[].class, a); Assertions.assertArrayEquals(new long[]{1L, 2L, 3L, 4L}, result); //数组转数组测试 - final byte[] resultBytes = (byte[]) CompositeConverter.getInstance().convert(byte[].class, a); + final byte[] resultBytes = CompositeConverter.getInstance().convert(byte[].class, a); Assertions.assertArrayEquals(new byte[]{1, 2, 3, 4}, resultBytes); //字符串转数组 diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/convert/EntryConvertTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/convert/EntryConvertTest.java index f63501765..6d79259f5 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/convert/EntryConvertTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/convert/EntryConvertTest.java @@ -31,7 +31,7 @@ public class EntryConvertTest { final KVBean kvBean = new KVBean(); kvBean.setKey("a"); kvBean.setValue(1); - final AbstractMap.SimpleEntry entry = (AbstractMap.SimpleEntry) CompositeConverter.getInstance() + final AbstractMap.SimpleEntry entry = CompositeConverter.getInstance() .convert(AbstractMap.SimpleEntry.class, kvBean); Assertions.assertEquals("a", entry.getKey()); @@ -42,7 +42,7 @@ public class EntryConvertTest { void beanToEntryTest2() { final SingleBean bean = new SingleBean(); bean.setA("1"); - final AbstractMap.SimpleEntry entry = (AbstractMap.SimpleEntry) CompositeConverter.getInstance() + final AbstractMap.SimpleEntry entry = CompositeConverter.getInstance() .convert(AbstractMap.SimpleEntry.class, bean); Assertions.assertEquals("a", entry.getKey()); @@ -53,7 +53,7 @@ public class EntryConvertTest { void mapToEntryTest() { final Map bean = new HashMap<>(); bean.put("a", 1); - final AbstractMap.SimpleEntry entry = (AbstractMap.SimpleEntry) CompositeConverter.getInstance() + final AbstractMap.SimpleEntry entry = CompositeConverter.getInstance() .convert(AbstractMap.SimpleEntry.class, bean); Assertions.assertEquals("a", entry.getKey()); @@ -63,7 +63,7 @@ public class EntryConvertTest { @Test void strToEntryTest() { final String bean = "a=1"; - final AbstractMap.SimpleEntry entry = (AbstractMap.SimpleEntry) CompositeConverter.getInstance() + final AbstractMap.SimpleEntry entry = CompositeConverter.getInstance() .convert(AbstractMap.SimpleEntry.class, bean); Assertions.assertEquals("a", entry.getKey()); @@ -73,7 +73,7 @@ public class EntryConvertTest { @Test void strToEntryTest2() { final String bean = "a:1"; - final AbstractMap.SimpleEntry entry = (AbstractMap.SimpleEntry) CompositeConverter.getInstance() + final AbstractMap.SimpleEntry entry = CompositeConverter.getInstance() .convert(AbstractMap.SimpleEntry.class, bean); Assertions.assertEquals("a", entry.getKey()); @@ -83,7 +83,7 @@ public class EntryConvertTest { @Test void strToEntryTest3() { final String bean = "a,1"; - final AbstractMap.SimpleEntry entry = (AbstractMap.SimpleEntry) CompositeConverter.getInstance() + final AbstractMap.SimpleEntry entry = CompositeConverter.getInstance() .convert(AbstractMap.SimpleEntry.class, bean); Assertions.assertEquals("a", entry.getKey()); diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/InternalJSONUtil.java b/hutool-json/src/main/java/org/dromara/hutool/json/InternalJSONUtil.java index 9ffd32266..e19000360 100644 --- a/hutool-json/src/main/java/org/dromara/hutool/json/InternalJSONUtil.java +++ b/hutool-json/src/main/java/org/dromara/hutool/json/InternalJSONUtil.java @@ -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()); } diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/JSONArray.java b/hutool-json/src/main/java/org/dromara/hutool/json/JSONArray.java index 441ddb5cc..e6804f1e0 100644 --- a/hutool-json/src/main/java/org/dromara/hutool/json/JSONArray.java +++ b/hutool-json/src/main/java/org/dromara/hutool/json/JSONArray.java @@ -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, List, RandomAccess { +public class JSONArray extends ListWrapper implements JSON, JSONGetter, RandomAccess { private static final long serialVersionUID = 2664900568717612292L; /** @@ -51,20 +47,12 @@ public class JSONArray implements JSON, JSONGetter, List, Rando */ public static final int DEFAULT_CAPACITY = 10; - /** - * 持有原始数据的List - */ - private List rawList; /** * 配置项 */ private JSONConfig config; - /** - * 对象转换和包装,用于将Java对象和值转换为JSON值 - */ - private JSONValueMapper valueMapper; - // region Constructors + // region ----- Constructors /** * 构造
@@ -105,66 +93,8 @@ public class JSONArray implements JSON, JSONGetter, List, 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}的值
- * 支持以下类型的参数: - * - *
-	 * 1. 数组
-	 * 2. {@link Iterable}对象
-	 * 3. JSON数组字符串
-	 * 
- * - * @param object 数组或集合或JSON数组字符串 - * @throws JSONException 非数组或集合 - */ - public JSONArray(final Object object) throws JSONException { - this(object, JSONConfig.of()); - } - - /** - * 从对象构造
- * 支持以下类型的参数: - * - *
-	 * 1. 数组
-	 * 2. {@link Iterable}对象
-	 * 3. JSON数组字符串
-	 * 
- * - * @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); - } - - /** - * 从对象构造
- * 支持以下类型的参数: - * - *
-	 * 1. 数组
-	 * 2. {@link Iterable}对象
-	 * 3. JSON数组字符串
-	 * 
- * - * @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> predicate) throws JSONException { - this(DEFAULT_CAPACITY, jsonConfig); - JSONArrayMapper.of(object, predicate).mapTo(this); } // endregion @@ -173,54 +103,21 @@ public class JSONArray implements JSON, JSONGetter, List, 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.
- * 加入元素,数组长度+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, List, 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 < 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, List, 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 iterator() { - return rawList.iterator(); + public Iterator iterator() { + return raw.iterator(); } /** @@ -309,7 +166,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando * @param type JSON类型 */ public Iterable jsonIter(final Class type) { - final Iterator iterator = iterator(); + final Iterator iterator = iterator(); return () -> new Iterator() { @Override public boolean hasNext() { @@ -327,26 +184,6 @@ public class JSONArray implements JSON, JSONGetter, List, 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[] toArray(final T[] a) { @@ -354,78 +191,29 @@ public class JSONArray implements JSON, JSONGetter, List, 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> 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 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 list = new ArrayList<>(c.size()); - for (final Object object : c) { - if (null == object && config.isIgnoreNullValue()) { + final List 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, List, 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 过滤器,可以修改值,key(index)无法修改,{@link Predicate#test(Object)}为{@code true}保留,null表示全部保留。 - * @return 替换的值,即之前的值 - * @since 5.8.0 - */ - public Object set(final int index, Object element, final Predicate> filter) { - // 添加前置过滤,通过MutablePair实现过滤、修改键值对等 - if (null != filter) { - final MutableEntry 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, List, 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, List, 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, List, 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 listIterator() { - return this.rawList.listIterator(); - } - - @Override - public ListIterator listIterator(final int index) { - return this.rawList.listIterator(index); - } - - @Override - public List subList(final int fromIndex, final int toIndex) { - return this.rawList.subList(fromIndex, toIndex); - } - /** * 转为Bean数组 * @@ -569,45 +310,15 @@ public class JSONArray implements JSON, JSONGetter, List, 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> predicate) { - // 添加前置过滤,通过MutablePair实现过滤、修改键值对等 - if (null != predicate) { - final Mutable 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); - } } diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/JSONGetter.java b/hutool-json/src/main/java/org/dromara/hutool/json/JSONGetter.java index f0069ffce..605cdfab0 100644 --- a/hutool-json/src/main/java/org/dromara/hutool/json/JSONGetter.java +++ b/hutool-json/src/main/java/org/dromara/hutool/json/JSONGetter.java @@ -87,7 +87,7 @@ public interface JSONGetter extends TypeGetter { if (object instanceof JSON) { return (JSONArray) object; } - return new JSONArray(object, config()); + return JSONUtil.parseArray(object, config()); } /** 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 334f4b4d9..59ea601e5 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 @@ -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 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 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 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 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; } diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/JSONUtil.java b/hutool-json/src/main/java/org/dromara/hutool/json/JSONUtil.java index 84d35d272..b2753662b 100644 --- a/hutool-json/src/main/java/org/dromara/hutool/json/JSONUtil.java +++ b/hutool-json/src/main/java/org/dromara/hutool/json/JSONUtil.java @@ -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对象
* 此方法会忽略空值,但是对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对象
* 此方法会忽略空值,但是对JSON字符串不影响 @@ -133,9 +122,7 @@ public class JSONUtil { * @return JSONObject */ public static JSONObject parseObj(final Object obj, final JSONConfig config, final Predicate> 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> predicate) { + return (JSONArray) parse(arrayOrCollection, config, predicate); } /** @@ -186,15 +186,34 @@ public class JSONUtil { *
  • Bean对象:转为JSONObject
  • * * - * @param obj 对象 - * @param config JSON配置,{@code null}使用默认配置 + * @param obj 对象 + * @param config JSON配置,{@code null}使用默认配置 * @return JSON(JSONObject 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的有序与否与传入对象有关。
    + * 支持的对象: + *
      + *
    • String: 转换为相应的对象
    • + *
    • Array、Iterable、Iterator:转换为JSONArray
    • + *
    • Bean对象:转为JSONObject
    • + *
    + * + * @param obj 对象 + * @param config JSON配置,{@code null}使用默认配置 + * @param predicate 键值对过滤编辑器,可以通过实现此接口,完成解析前对键值对的过滤和修改操作,{@link Predicate#test(Object)}为{@code true}保留 + * @return JSON(JSONObject or JSONArray) + */ + public static JSON parse(final Object obj, final JSONConfig config, final Predicate> 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); } /** 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 8caeb7ae5..5a69147f7 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 @@ -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 serializer = - (JSONSerializer) 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 rawType = (Class) 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); } diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/jwt/JWT.java b/hutool-json/src/main/java/org/dromara/hutool/json/jwt/JWT.java index 177cf242d..611d4d6a0 100644 --- a/hutool-json/src/main/java/org/dromara/hutool/json/jwt/JWT.java +++ b/hutool-json/src/main/java/org/dromara/hutool/json/jwt/JWT.java @@ -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 { * @throws ValidateException 传入的类型不匹配payload类型 * @since 6.0.0 */ - public T getPayload(final String propertyName, final Class propertyType) { + public T getPayload(final String propertyName, final Type propertyType) { return getPayload().getClaimsJson().get(propertyName, propertyType); } 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 35a0ec58c..d1ed9af41 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 @@ -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 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); - } - } - /** * 初始化 * 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 c2ea8283e..11e8a3385 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 @@ -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; * * * @author looly - * @since 5.8.0 */ -public class JSONObjectMapper { +class JSONObjectMapper { /** * 创建ObjectMapper @@ -96,13 +90,6 @@ public class JSONObjectMapper { return; } - // 自定义序列化 - final JSONSerializer 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}转换 * diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/mapper/JSONValueMapper.java b/hutool-json/src/main/java/org/dromara/hutool/json/mapper/JSONValueMapper.java index daf858387..5b717d980 100644 --- a/hutool-json/src/main/java/org/dromara/hutool/json/mapper/JSONValueMapper.java +++ b/hutool-json/src/main/java/org/dromara/hutool/json/mapper/JSONValueMapper.java @@ -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对象中的值
    @@ -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> predicate) { + return new JSONValueMapper(jsonConfig, predicate); } private final JSONConfig jsonConfig; + private final Predicate> 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> 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 { *
  • 其它 =》 尝试包装为JSONObject,否则返回{@code null}
  • * * - * @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 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); 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 6db46abde..a1d20dacd 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 @@ -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 entry = MutableEntry.of(jsonArray.size(), value); if (predicate.test(entry)) { // 使用修改后的键值对 - value = entry.getValue(); + value = (JSON) entry.getValue(); jsonArray.add(value); } } else { diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/serializer/SerializerManager.java b/hutool-json/src/main/java/org/dromara/hutool/json/serializer/SerializerManager.java index 971ef814c..52926cc4d 100644 --- a/hutool-json/src/main/java/org/dromara/hutool/json/serializer/SerializerManager.java +++ b/hutool-json/src/main/java/org/dromara/hutool/json/serializer/SerializerManager.java @@ -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 getSerializer(final Object bean) { + for (final MatcherJSONSerializer serializer : this.serializerSet) { if (serializer.match(bean, null)) { - return serializer; + return (JSONSerializer) serializer; } } return null; diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/writer/JSONWriter.java b/hutool-json/src/main/java/org/dromara/hutool/json/writer/JSONWriter.java index 6a97aac5e..84f319626 100644 --- a/hutool-json/src/main/java/org/dromara/hutool/json/writer/JSONWriter.java +++ b/hutool-json/src/main/java/org/dromara/hutool/json/writer/JSONWriter.java @@ -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); diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/writer/ValueWriterManager.java b/hutool-json/src/main/java/org/dromara/hutool/json/writer/ValueWriterManager.java index 09625d146..8bae636c8 100644 --- a/hutool-json/src/main/java/org/dromara/hutool/json/writer/ValueWriterManager.java +++ b/hutool-json/src/main/java/org/dromara/hutool/json/writer/ValueWriterManager.java @@ -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); diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/xml/JSONXMLSerializer.java b/hutool-json/src/main/java/org/dromara/hutool/json/xml/JSONXMLSerializer.java index 66dae00dc..12fae5abc 100644 --- a/hutool-json/src/main/java/org/dromara/hutool/json/xml/JSONXMLSerializer.java +++ b/hutool-json/src/main/java/org/dromara/hutool/json/xml/JSONXMLSerializer.java @@ -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) { diff --git a/hutool-json/src/test/java/org/dromara/hutool/json/Issue3274Test.java b/hutool-json/src/test/java/org/dromara/hutool/json/Issue3274Test.java index e1490c9b5..e80e09203 100755 --- a/hutool-json/src/test/java/org/dromara/hutool/json/Issue3274Test.java +++ b/hutool-json/src/test/java/org/dromara/hutool/json/Issue3274Test.java @@ -51,7 +51,7 @@ public class Issue3274Test { Gender(final String enum_name, final String en_Us, final String zh_CN) { this.enum_name = enum_name; - this.display = new JSONArray("[{\"lang\": \"en-US\",\"value\": \"" + en_Us + "\"},{\"lang\": \"zh-CN\",\"value\": \"" + zh_CN + "\"}]"); + this.display = JSONUtil.parseArray("[{\"lang\": \"en-US\",\"value\": \"" + en_Us + "\"},{\"lang\": \"zh-CN\",\"value\": \"" + zh_CN + "\"}]"); } } } diff --git a/hutool-json/src/test/java/org/dromara/hutool/json/IssueI9DX5HTest.java b/hutool-json/src/test/java/org/dromara/hutool/json/IssueI9DX5HTest.java index a313f2ed3..7c0a89bb0 100644 --- a/hutool-json/src/test/java/org/dromara/hutool/json/IssueI9DX5HTest.java +++ b/hutool-json/src/test/java/org/dromara/hutool/json/IssueI9DX5HTest.java @@ -17,7 +17,7 @@ package org.dromara.hutool.json; import org.dromara.hutool.core.text.StrUtil; -import org.dromara.hutool.json.mapper.JSONObjectMapper; +import org.dromara.hutool.json.mapper.JSONValueMapper; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -27,12 +27,11 @@ public class IssueI9DX5HTest { @Test void xmlToJSONTest() { final String xml = "你好"; - final JSONObjectMapper mapper = JSONObjectMapper.of(xml, entry -> { + final JSONValueMapper mapper = JSONValueMapper.of(JSONConfig.of(), entry -> { entry.setKey(StrUtil.toUnderlineCase((CharSequence) entry.getKey())); return true; }); - final JSONObject jsonObject = new JSONObject(); - mapper.mapTo(jsonObject); + final JSONObject jsonObject = (JSONObject) mapper.map(xml); Assertions.assertEquals("{\"good_msg\":\"你好\"}", jsonObject.toString()); } diff --git a/hutool-json/src/test/java/org/dromara/hutool/json/JSONArrayTest.java b/hutool-json/src/test/java/org/dromara/hutool/json/JSONArrayTest.java index 41c71fb1f..3222bceee 100644 --- a/hutool-json/src/test/java/org/dromara/hutool/json/JSONArrayTest.java +++ b/hutool-json/src/test/java/org/dromara/hutool/json/JSONArrayTest.java @@ -48,11 +48,11 @@ public class JSONArrayTest { // JSONObject实现了Iterable接口,可以转换为JSONArray final JSONObject jsonObject = new JSONObject(); - JSONArray jsonArray = new JSONArray(jsonObject, JSONConfig.of()); + JSONArray jsonArray = JSONUtil.parseArray(jsonObject, JSONConfig.of()); assertEquals(new JSONArray(), jsonArray); jsonObject.set("key1", "value1"); - jsonArray = new JSONArray(jsonObject, JSONConfig.of()); + jsonArray = JSONUtil.parseArray(jsonObject, JSONConfig.of()); assertEquals(1, jsonArray.size()); assertEquals("[{\"key1\":\"value1\"}]", jsonArray.toString()); } @@ -70,9 +70,9 @@ public class JSONArrayTest { final JSONArray array = JSONUtil.ofArray(); // 方法2 // JSONArray array = new JSONArray(); - array.add("value1"); - array.add("value2"); - array.add("value3"); + array.set("value1"); + array.set("value2"); + array.set("value3"); assertEquals(array.get(0), "value1"); } @@ -238,12 +238,12 @@ public class JSONArrayTest { @Test public void putToIndexTest() { JSONArray jsonArray = new JSONArray(); - jsonArray.set(3, "test"); + jsonArray.setValue(3, "test"); // 默认忽略null值,因此空位无值,只有一个值 assertEquals(1, jsonArray.size()); jsonArray = new JSONArray(JSONConfig.of().setIgnoreNullValue(false)); - jsonArray.set(2, "test"); + jsonArray.setValue(2, "test"); // 第三个位置插入值,0~2都是null assertEquals(3, jsonArray.size()); } @@ -252,7 +252,7 @@ public class JSONArrayTest { @Test public void putTest2() { final JSONArray jsonArray = new JSONArray(); - jsonArray.put(0, 1); + jsonArray.setValue(0, 1); assertEquals(1, jsonArray.size()); assertEquals(1, jsonArray.get(0)); } @@ -307,7 +307,7 @@ public class JSONArrayTest { public void parseFilterTest() { final String jsonArr = "[{\"id\":111,\"name\":\"test1\"},{\"id\":112,\"name\":\"test2\"}]"; //noinspection MismatchedQueryAndUpdateOfCollection - final JSONArray array = new JSONArray(jsonArr, null, (mutable) -> mutable.get().toString().contains("111")); + final JSONArray array = JSONUtil.parseArray(jsonArr, null, (mutable) -> mutable.get().toString().contains("111")); assertEquals(1, array.size()); assertTrue(array.getJSONObject(0).containsKey("id")); } @@ -316,7 +316,7 @@ public class JSONArrayTest { public void parseFilterEditTest() { final String jsonArr = "[{\"id\":111,\"name\":\"test1\"},{\"id\":112,\"name\":\"test2\"}]"; //noinspection MismatchedQueryAndUpdateOfCollection - final JSONArray array = new JSONArray(jsonArr, null, (mutable) -> { + final JSONArray array = JSONUtil.parseArray(jsonArr, null, (mutable) -> { if(mutable.getKey() instanceof Integer){ final JSONObject o = (JSONObject) mutable.getValue(); if ("111".equals(o.getStr("id"))) { diff --git a/hutool-json/src/test/java/org/dromara/hutool/json/JSONNullTest.java b/hutool-json/src/test/java/org/dromara/hutool/json/JSONNullTest.java index 6d1a26a7e..40b6014ba 100644 --- a/hutool-json/src/test/java/org/dromara/hutool/json/JSONNullTest.java +++ b/hutool-json/src/test/java/org/dromara/hutool/json/JSONNullTest.java @@ -42,7 +42,7 @@ public class JSONNullTest { " \"device_model\": null,\n" + " \"device_status_date\": null,\n" + " \"imsi\": null,\n" + - " \"act_date\": \"2021-07-23T06:23:26.000+00:00\"}", true); + " \"act_date\": \"2021-07-23T06:23:26.000+00:00\"}"); Assertions.assertFalse(bodyjson.containsKey("device_model")); Assertions.assertFalse(bodyjson.containsKey("device_status_date")); Assertions.assertFalse(bodyjson.containsKey("imsi")); diff --git a/hutool-json/src/test/java/org/dromara/hutool/json/JSONObjectTest.java b/hutool-json/src/test/java/org/dromara/hutool/json/JSONObjectTest.java index 95167891d..9a4d3c943 100644 --- a/hutool-json/src/test/java/org/dromara/hutool/json/JSONObjectTest.java +++ b/hutool-json/src/test/java/org/dromara/hutool/json/JSONObjectTest.java @@ -313,7 +313,7 @@ public class JSONObjectTest { userA.setDate(new Date()); userA.setSqs(ListUtil.of(new Seq(null), new Seq("seq2"))); - final JSONObject json = JSONUtil.parseObj(userA, false); + final JSONObject json = JSONUtil.parseObj(userA, JSONConfig.of().setIgnoreNullValue(false)); Assertions.assertTrue(json.containsKey("a")); Assertions.assertTrue(json.getJSONArray("sqs").getJSONObject(0).containsKey("seq")); @@ -328,7 +328,8 @@ public class JSONObjectTest { bean.setStrValue("strTest"); bean.setTestEnum(TestEnum.TYPE_B); - final JSONObject json = JSONUtil.parseObj(bean, false); + final JSONObject json = JSONUtil.parseObj(bean, + JSONConfig.of().setIgnoreNullValue(false)); // 枚举转换检查,更新:枚举原样保存,在writer时调用toString。 Assertions.assertEquals(TestEnum.TYPE_B, json.getObj("testEnum")); @@ -396,7 +397,8 @@ public class JSONObjectTest { final JSONObject userAJson = JSONUtil.parseObj(userA); Assertions.assertFalse(userAJson.containsKey("a")); - final JSONObject userAJsonWithNullValue = JSONUtil.parseObj(userA, false); + final JSONObject userAJsonWithNullValue = JSONUtil.parseObj(userA, + JSONConfig.of().setIgnoreNullValue(false)); Assertions.assertTrue(userAJsonWithNullValue.containsKey("a")); Assertions.assertTrue(userAJsonWithNullValue.containsKey("sqs")); } diff --git a/hutool-json/src/test/java/org/dromara/hutool/json/JSONTokenerTest.java b/hutool-json/src/test/java/org/dromara/hutool/json/JSONTokenerTest.java index d5c7740c7..6b31e854f 100644 --- a/hutool-json/src/test/java/org/dromara/hutool/json/JSONTokenerTest.java +++ b/hutool-json/src/test/java/org/dromara/hutool/json/JSONTokenerTest.java @@ -18,6 +18,7 @@ package org.dromara.hutool.json; import org.dromara.hutool.core.io.IoUtil; import org.dromara.hutool.core.io.resource.ResourceUtil; +import org.dromara.hutool.core.lang.Console; import org.dromara.hutool.json.reader.JSONTokener; import org.junit.jupiter.api.Test; @@ -29,6 +30,7 @@ public class JSONTokenerTest { void parseTest() { final JSONObject jsonObject = JSONUtil.parseObj(ResourceUtil.getUtf8Reader("issue1200.json")); assertNotNull(jsonObject); + Console.log(jsonObject.toStringPretty()); } @Test diff --git a/hutool-json/src/test/java/org/dromara/hutool/json/TransientTest.java b/hutool-json/src/test/java/org/dromara/hutool/json/TransientTest.java index 1eabe83df..d0791eec9 100644 --- a/hutool-json/src/test/java/org/dromara/hutool/json/TransientTest.java +++ b/hutool-json/src/test/java/org/dromara/hutool/json/TransientTest.java @@ -37,6 +37,7 @@ public class TransientTest { //noinspection MismatchedQueryAndUpdateOfCollection final JSONObject jsonObject = JSONUtil.parseObj(detailBill, JSONConfig.of().setTransientSupport(false)); + Assertions.assertEquals("{\"id\":\"3243\",\"bizNo\":\"bizNo\"}", jsonObject.toString()); } diff --git a/hutool-json/src/test/java/org/dromara/hutool/json/engine/GsonTest.java b/hutool-json/src/test/java/org/dromara/hutool/json/engine/GsonTest.java index 0a1037ccc..a4e9b169a 100644 --- a/hutool-json/src/test/java/org/dromara/hutool/json/engine/GsonTest.java +++ b/hutool-json/src/test/java/org/dromara/hutool/json/engine/GsonTest.java @@ -16,12 +16,15 @@ package org.dromara.hutool.json.engine; +import org.dromara.hutool.core.collection.ListUtil; import org.dromara.hutool.core.date.DateTime; import org.dromara.hutool.core.date.DateUtil; import org.dromara.hutool.core.date.TimeUtil; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import java.util.ArrayList; + public class GsonTest { /** * Gson默认缩进两个空格,使用\n换行符 @@ -54,4 +57,11 @@ public class GsonTest { Assertions.assertEquals("{\"date\":\"2024-01-01 00:00:00\"}", engine.toJsonString(bean)); } + @Test + void arrayToStringTest() { + final ArrayList integers = ListUtil.of(1, 2, 3); + final JSONEngine engine = JSONEngineFactory.createEngine("gson"); + final String jsonString = engine.toJsonString(integers); + Assertions.assertEquals("[1,2,3]", jsonString); + } } diff --git a/hutool-json/src/test/java/org/dromara/hutool/json/jwt/JWTTest.java b/hutool-json/src/test/java/org/dromara/hutool/json/jwt/JWTTest.java index 93251f181..c5df11bfd 100644 --- a/hutool-json/src/test/java/org/dromara/hutool/json/jwt/JWTTest.java +++ b/hutool-json/src/test/java/org/dromara/hutool/json/jwt/JWTTest.java @@ -16,13 +16,16 @@ package org.dromara.hutool.json.jwt; +import lombok.Data; +import org.dromara.hutool.core.collection.CollUtil; import org.dromara.hutool.core.date.DatePattern; import org.dromara.hutool.core.date.DateUtil; +import org.dromara.hutool.core.reflect.TypeReference; +import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.util.ByteUtil; import org.dromara.hutool.json.jwt.signers.AlgorithmUtil; import org.dromara.hutool.json.jwt.signers.JWTSigner; import org.dromara.hutool.json.jwt.signers.JWTSignerUtil; -import lombok.Data; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -132,12 +135,12 @@ public class JWTTest { final List list = Arrays.asList(1, 2, 3); final Integer num = 18; final String username = "takaki"; - final HashMap map = new HashMap<>(); + final Map map = new HashMap<>(); map.put("test1", "1"); map.put("test2", "2"); + final Map payload = new HashMap() { private static final long serialVersionUID = 1L; - { put("username", username); put("bean", bean); @@ -155,17 +158,20 @@ public class JWTTest { final Date dateRes = jwt.getPayload("date", Date.class); final List listRes = jwt.getPayload("list", List.class); final Integer numRes = jwt.getPayload("number", Integer.class); - final HashMap mapRes = jwt.getPayload("map", HashMap.class); + final Map mapRes = jwt.getPayload("map", new TypeReference>(){}); Assertions.assertEquals(bean, beanRes); Assertions.assertEquals(numRes, num); Assertions.assertEquals(username, strRes); - Assertions.assertEquals(list, listRes); + Assertions.assertEquals( + StrUtil.wrap(CollUtil.join(list, ","), "[", "]"), + listRes.toString()); final String formattedDate = DateUtil.format(date, "yyyy-MM-dd HH:mm:ss"); final String formattedRes = DateUtil.format(dateRes, "yyyy-MM-dd HH:mm:ss"); Assertions.assertEquals(formattedDate, formattedRes); - Assertions.assertEquals(map, mapRes); + Assertions.assertEquals(map.get("test1"), mapRes.get("test1")); + Assertions.assertEquals(map.get("test2"), mapRes.get("test2")); } @Test()