mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-19 03:01:48 +08:00
fix code
This commit is contained in:
parent
c489cc7735
commit
bc3f6cf1ee
@ -454,7 +454,6 @@ public class BeanUtil {
|
|||||||
* @param ignoreProperties 不拷贝的的属性列表
|
* @param ignoreProperties 不拷贝的的属性列表
|
||||||
* @return 目标对象
|
* @return 目标对象
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static <T> T copyProperties(final Object source, final Class<T> tClass, final String... ignoreProperties) {
|
public static <T> T copyProperties(final Object source, final Class<T> tClass, final String... ignoreProperties) {
|
||||||
if (null == source) {
|
if (null == source) {
|
||||||
return null;
|
return null;
|
||||||
@ -462,7 +461,7 @@ public class BeanUtil {
|
|||||||
if (RecordUtil.isRecord(tClass)) {
|
if (RecordUtil.isRecord(tClass)) {
|
||||||
// issue#I7EO3U
|
// issue#I7EO3U
|
||||||
// 转换record时,ignoreProperties无效
|
// 转换record时,ignoreProperties无效
|
||||||
return (T) RecordConverter.INSTANCE.convert(tClass, source);
|
return RecordConverter.INSTANCE.convert(tClass, source);
|
||||||
}
|
}
|
||||||
final T target = ConstructorUtil.newInstanceIfPossible(tClass);
|
final T target = ConstructorUtil.newInstanceIfPossible(tClass);
|
||||||
return copyProperties(source, target, CopyOptions.of().setIgnoreProperties(ignoreProperties));
|
return copyProperties(source, target, CopyOptions.of().setIgnoreProperties(ignoreProperties));
|
||||||
|
@ -1955,7 +1955,7 @@ public class CollUtil {
|
|||||||
* @param consumer {@link SerBiConsumer} 遍历的每条数据处理器
|
* @param consumer {@link SerBiConsumer} 遍历的每条数据处理器
|
||||||
* @since 5.4.7
|
* @since 5.4.7
|
||||||
*/
|
*/
|
||||||
public static <T> void forEach(final Iterable<T> iterable, final SerBiConsumer<T, Integer> consumer) {
|
public static <T> void forEach(final Iterable<T> iterable, final SerBiConsumer<Integer, T> consumer) {
|
||||||
if (iterable == null) {
|
if (iterable == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1969,13 +1969,13 @@ public class CollUtil {
|
|||||||
* @param iterator {@link Iterator}
|
* @param iterator {@link Iterator}
|
||||||
* @param consumer {@link SerBiConsumer} 遍历的每条数据处理器
|
* @param consumer {@link SerBiConsumer} 遍历的每条数据处理器
|
||||||
*/
|
*/
|
||||||
public static <T> void forEach(final Iterator<T> iterator, final SerBiConsumer<T, Integer> consumer) {
|
public static <T> void forEach(final Iterator<T> iterator, final SerBiConsumer<Integer, T> consumer) {
|
||||||
if (iterator == null) {
|
if (iterator == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int index = 0;
|
int index = 0;
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
consumer.accept(iterator.next(), index);
|
consumer.accept(index, iterator.next());
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1987,13 +1987,13 @@ public class CollUtil {
|
|||||||
* @param enumeration {@link Enumeration}
|
* @param enumeration {@link Enumeration}
|
||||||
* @param consumer {@link SerBiConsumer} 遍历的每条数据处理器
|
* @param consumer {@link SerBiConsumer} 遍历的每条数据处理器
|
||||||
*/
|
*/
|
||||||
public static <T> void forEach(final Enumeration<T> enumeration, final SerBiConsumer<T, Integer> consumer) {
|
public static <T> void forEach(final Enumeration<T> enumeration, final SerBiConsumer<Integer, T> consumer) {
|
||||||
if (enumeration == null) {
|
if (enumeration == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int index = 0;
|
int index = 0;
|
||||||
while (enumeration.hasMoreElements()) {
|
while (enumeration.hasMoreElements()) {
|
||||||
consumer.accept(enumeration.nextElement(), index);
|
consumer.accept(index, enumeration.nextElement());
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2007,13 +2007,13 @@ public class CollUtil {
|
|||||||
* @param map {@link Map}
|
* @param map {@link Map}
|
||||||
* @param kvConsumer {@link SerConsumer3} 遍历的每条数据处理器
|
* @param kvConsumer {@link SerConsumer3} 遍历的每条数据处理器
|
||||||
*/
|
*/
|
||||||
public static <K, V> void forEach(final Map<K, V> map, final SerConsumer3<K, V, Integer> kvConsumer) {
|
public static <K, V> void forEach(final Map<K, V> map, final SerConsumer3<Integer, K, V> kvConsumer) {
|
||||||
if (map == null) {
|
if (map == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (final Entry<K, V> entry : map.entrySet()) {
|
for (final Entry<K, V> entry : map.entrySet()) {
|
||||||
kvConsumer.accept(entry.getKey(), entry.getValue(), index);
|
kvConsumer.accept(index, entry.getKey(), entry.getValue());
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -191,4 +191,21 @@ public class ListWrapper<E> extends SimpleWrapper<List<E>> implements List<E> {
|
|||||||
public Stream<E> parallelStream() {
|
public Stream<E> parallelStream() {
|
||||||
return raw.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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -561,10 +561,9 @@ public class ConvertUtil {
|
|||||||
* @param defaultValue 默认值
|
* @param defaultValue 默认值
|
||||||
* @return Enum
|
* @return Enum
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static <E extends Enum<E>> E toEnum(final Class<E> clazz, final Object value, final E defaultValue) {
|
public static <E extends Enum<E>> E toEnum(final Class<E> clazz, final Object value, final E defaultValue) {
|
||||||
try {
|
try {
|
||||||
return (E) EnumConverter.INSTANCE.convert(clazz, value);
|
return EnumConverter.INSTANCE.convert(clazz, value);
|
||||||
} catch (final Exception ignore) {
|
} catch (final Exception ignore) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,21 @@ public interface Converter {
|
|||||||
*/
|
*/
|
||||||
Object convert(Type targetType, Object value) throws ConvertException;
|
Object convert(Type targetType, Object value) throws ConvertException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为指定类型<br>
|
||||||
|
* 如果类型无法确定,将读取默认值的类型做为目标类型
|
||||||
|
*
|
||||||
|
* @param <T> 目标类型
|
||||||
|
* @param targetType 目标类型
|
||||||
|
* @param value 原始值,如果对象实现了此接口,则value为this
|
||||||
|
* @return 转换后的值
|
||||||
|
* @throws ConvertException 转换无法正常完成或转换异常时抛出此异常
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
default <T> T convert(final Class<T> targetType, final Object value) throws ConvertException {
|
||||||
|
return (T) convert((Type) targetType, value);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 转换值为指定类型,可选是否不抛异常转换<br>
|
* 转换值为指定类型,可选是否不抛异常转换<br>
|
||||||
* 当转换失败时返回默认值
|
* 当转换失败时返回默认值
|
||||||
@ -57,9 +72,10 @@ public interface Converter {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回原值的转换器,不做转换
|
* 返回原值的转换器,不做转换
|
||||||
|
*
|
||||||
* @return Converter
|
* @return Converter
|
||||||
*/
|
*/
|
||||||
static Converter identity(){
|
static Converter identity() {
|
||||||
return (targetType, value) -> value;
|
return (targetType, value) -> value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ public class TupleConverter implements Converter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object convert(final Type targetType, final Object value) throws ConvertException {
|
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);
|
return Tuple.of(convert);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -321,7 +321,7 @@ public class CollUtilTest {
|
|||||||
|
|
||||||
final String[] result = new String[1];
|
final String[] result = new String[1];
|
||||||
final String a = "a";
|
final String a = "a";
|
||||||
CollUtil.forEach(map, (key, value, index) -> {
|
CollUtil.forEach(map, (index, key, value) -> {
|
||||||
if (a.equals(key)) {
|
if (a.equals(key)) {
|
||||||
result[0] = value;
|
result[0] = value;
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
|
|||||||
public class CompositeConverterTest {
|
public class CompositeConverterTest {
|
||||||
@Test
|
@Test
|
||||||
void convertEmptyTest() {
|
void convertEmptyTest() {
|
||||||
final Object convert = CompositeConverter.getInstance().convert(EmptyBean.class, "");
|
final EmptyBean convert = CompositeConverter.getInstance().convert(EmptyBean.class, "");
|
||||||
assertNotNull(convert);
|
assertNotNull(convert);
|
||||||
assertEquals(new EmptyBean(), convert);
|
assertEquals(new EmptyBean(), convert);
|
||||||
}
|
}
|
||||||
@ -45,13 +45,13 @@ public class CompositeConverterTest {
|
|||||||
final int a = 454553;
|
final int a = 454553;
|
||||||
final CompositeConverter compositeConverter = CompositeConverter.getInstance();
|
final CompositeConverter compositeConverter = CompositeConverter.getInstance();
|
||||||
|
|
||||||
CharSequence result = (CharSequence) compositeConverter.convert(CharSequence.class, a);
|
CharSequence result = compositeConverter.convert(CharSequence.class, a);
|
||||||
assertEquals("454553", result);
|
assertEquals("454553", result);
|
||||||
|
|
||||||
//此处做为示例自定义CharSequence转换,因为Hutool中已经提供CharSequence转换,请尽量不要替换
|
//此处做为示例自定义CharSequence转换,因为Hutool中已经提供CharSequence转换,请尽量不要替换
|
||||||
//替换可能引发关联转换异常(例如覆盖CharSequence转换会影响全局)
|
//替换可能引发关联转换异常(例如覆盖CharSequence转换会影响全局)
|
||||||
compositeConverter.register(CharSequence.class, new CustomConverter());
|
compositeConverter.register(CharSequence.class, new CustomConverter());
|
||||||
result = (CharSequence) compositeConverter.convert(CharSequence.class, a);
|
result = compositeConverter.convert(CharSequence.class, a);
|
||||||
assertEquals("Custom: 454553", result);
|
assertEquals("Custom: 454553", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,28 +131,28 @@ public class ConvertTest {
|
|||||||
final String a = " 34232";
|
final String a = " 34232";
|
||||||
final Integer aInteger = ConvertUtil.toInt(a);
|
final Integer aInteger = ConvertUtil.toInt(a);
|
||||||
assertEquals(Integer.valueOf(34232), aInteger);
|
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);
|
assertEquals(34232, aInt);
|
||||||
|
|
||||||
// 带小数测试
|
// 带小数测试
|
||||||
final String b = " 34232.00";
|
final String b = " 34232.00";
|
||||||
final Integer bInteger = ConvertUtil.toInt(b);
|
final Integer bInteger = ConvertUtil.toInt(b);
|
||||||
assertEquals(Integer.valueOf(34232), bInteger);
|
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);
|
assertEquals(34232, bInt);
|
||||||
|
|
||||||
// boolean测试
|
// boolean测试
|
||||||
final boolean c = true;
|
final boolean c = true;
|
||||||
final Integer cInteger = ConvertUtil.toInt(c);
|
final Integer cInteger = ConvertUtil.toInt(c);
|
||||||
assertEquals(Integer.valueOf(1), cInteger);
|
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);
|
assertEquals(1, cInt);
|
||||||
|
|
||||||
// boolean测试
|
// boolean测试
|
||||||
final String d = "08";
|
final String d = "08";
|
||||||
final Integer dInteger = ConvertUtil.toInt(d);
|
final Integer dInteger = ConvertUtil.toInt(d);
|
||||||
assertEquals(Integer.valueOf(8), dInteger);
|
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);
|
assertEquals(8, dInt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,28 +176,28 @@ public class ConvertTest {
|
|||||||
final String a = " 342324545435435";
|
final String a = " 342324545435435";
|
||||||
final Long aLong = ConvertUtil.toLong(a);
|
final Long aLong = ConvertUtil.toLong(a);
|
||||||
assertEquals(Long.valueOf(342324545435435L), aLong);
|
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);
|
assertEquals(342324545435435L, aLong2);
|
||||||
|
|
||||||
// 带小数测试
|
// 带小数测试
|
||||||
final String b = " 342324545435435.245435435";
|
final String b = " 342324545435435.245435435";
|
||||||
final Long bLong = ConvertUtil.toLong(b);
|
final Long bLong = ConvertUtil.toLong(b);
|
||||||
assertEquals(Long.valueOf(342324545435435L), bLong);
|
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);
|
assertEquals(342324545435435L, bLong2);
|
||||||
|
|
||||||
// boolean测试
|
// boolean测试
|
||||||
final boolean c = true;
|
final boolean c = true;
|
||||||
final Long cLong = ConvertUtil.toLong(c);
|
final Long cLong = ConvertUtil.toLong(c);
|
||||||
assertEquals(Long.valueOf(1), cLong);
|
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);
|
assertEquals(1, cLong2);
|
||||||
|
|
||||||
// boolean测试
|
// boolean测试
|
||||||
final String d = "08";
|
final String d = "08";
|
||||||
final Long dLong = ConvertUtil.toLong(d);
|
final Long dLong = ConvertUtil.toLong(d);
|
||||||
assertEquals(Long.valueOf(8), dLong);
|
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);
|
assertEquals(8, dLong2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,11 +95,11 @@ public class ConvertToArrayTest {
|
|||||||
|
|
||||||
//数组转数组测试
|
//数组转数组测试
|
||||||
final int[] a = new int[]{1,2,3,4};
|
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);
|
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);
|
Assertions.assertArrayEquals(new byte[]{1, 2, 3, 4}, resultBytes);
|
||||||
|
|
||||||
//字符串转数组
|
//字符串转数组
|
||||||
|
@ -31,7 +31,7 @@ public class EntryConvertTest {
|
|||||||
final KVBean kvBean = new KVBean();
|
final KVBean kvBean = new KVBean();
|
||||||
kvBean.setKey("a");
|
kvBean.setKey("a");
|
||||||
kvBean.setValue(1);
|
kvBean.setValue(1);
|
||||||
final AbstractMap.SimpleEntry<?, ?> entry = (AbstractMap.SimpleEntry<?, ?>) CompositeConverter.getInstance()
|
final AbstractMap.SimpleEntry<?, ?> entry = CompositeConverter.getInstance()
|
||||||
.convert(AbstractMap.SimpleEntry.class, kvBean);
|
.convert(AbstractMap.SimpleEntry.class, kvBean);
|
||||||
|
|
||||||
Assertions.assertEquals("a", entry.getKey());
|
Assertions.assertEquals("a", entry.getKey());
|
||||||
@ -42,7 +42,7 @@ public class EntryConvertTest {
|
|||||||
void beanToEntryTest2() {
|
void beanToEntryTest2() {
|
||||||
final SingleBean bean = new SingleBean();
|
final SingleBean bean = new SingleBean();
|
||||||
bean.setA("1");
|
bean.setA("1");
|
||||||
final AbstractMap.SimpleEntry<?, ?> entry = (AbstractMap.SimpleEntry<?, ?>) CompositeConverter.getInstance()
|
final AbstractMap.SimpleEntry<?, ?> entry = CompositeConverter.getInstance()
|
||||||
.convert(AbstractMap.SimpleEntry.class, bean);
|
.convert(AbstractMap.SimpleEntry.class, bean);
|
||||||
|
|
||||||
Assertions.assertEquals("a", entry.getKey());
|
Assertions.assertEquals("a", entry.getKey());
|
||||||
@ -53,7 +53,7 @@ public class EntryConvertTest {
|
|||||||
void mapToEntryTest() {
|
void mapToEntryTest() {
|
||||||
final Map<String, Integer> bean = new HashMap<>();
|
final Map<String, Integer> bean = new HashMap<>();
|
||||||
bean.put("a", 1);
|
bean.put("a", 1);
|
||||||
final AbstractMap.SimpleEntry<?, ?> entry = (AbstractMap.SimpleEntry<?, ?>) CompositeConverter.getInstance()
|
final AbstractMap.SimpleEntry<?, ?> entry = CompositeConverter.getInstance()
|
||||||
.convert(AbstractMap.SimpleEntry.class, bean);
|
.convert(AbstractMap.SimpleEntry.class, bean);
|
||||||
|
|
||||||
Assertions.assertEquals("a", entry.getKey());
|
Assertions.assertEquals("a", entry.getKey());
|
||||||
@ -63,7 +63,7 @@ public class EntryConvertTest {
|
|||||||
@Test
|
@Test
|
||||||
void strToEntryTest() {
|
void strToEntryTest() {
|
||||||
final String bean = "a=1";
|
final String bean = "a=1";
|
||||||
final AbstractMap.SimpleEntry<?, ?> entry = (AbstractMap.SimpleEntry<?, ?>) CompositeConverter.getInstance()
|
final AbstractMap.SimpleEntry<?, ?> entry = CompositeConverter.getInstance()
|
||||||
.convert(AbstractMap.SimpleEntry.class, bean);
|
.convert(AbstractMap.SimpleEntry.class, bean);
|
||||||
|
|
||||||
Assertions.assertEquals("a", entry.getKey());
|
Assertions.assertEquals("a", entry.getKey());
|
||||||
@ -73,7 +73,7 @@ public class EntryConvertTest {
|
|||||||
@Test
|
@Test
|
||||||
void strToEntryTest2() {
|
void strToEntryTest2() {
|
||||||
final String bean = "a:1";
|
final String bean = "a:1";
|
||||||
final AbstractMap.SimpleEntry<?, ?> entry = (AbstractMap.SimpleEntry<?, ?>) CompositeConverter.getInstance()
|
final AbstractMap.SimpleEntry<?, ?> entry = CompositeConverter.getInstance()
|
||||||
.convert(AbstractMap.SimpleEntry.class, bean);
|
.convert(AbstractMap.SimpleEntry.class, bean);
|
||||||
|
|
||||||
Assertions.assertEquals("a", entry.getKey());
|
Assertions.assertEquals("a", entry.getKey());
|
||||||
@ -83,7 +83,7 @@ public class EntryConvertTest {
|
|||||||
@Test
|
@Test
|
||||||
void strToEntryTest3() {
|
void strToEntryTest3() {
|
||||||
final String bean = "a,1";
|
final String bean = "a,1";
|
||||||
final AbstractMap.SimpleEntry<?, ?> entry = (AbstractMap.SimpleEntry<?, ?>) CompositeConverter.getInstance()
|
final AbstractMap.SimpleEntry<?, ?> entry = CompositeConverter.getInstance()
|
||||||
.convert(AbstractMap.SimpleEntry.class, bean);
|
.convert(AbstractMap.SimpleEntry.class, bean);
|
||||||
|
|
||||||
Assertions.assertEquals("a", entry.getKey());
|
Assertions.assertEquals("a", entry.getKey());
|
||||||
|
@ -113,9 +113,9 @@ public final class InternalJSONUtil {
|
|||||||
return JSONUtil.parseObj(map).toString();
|
return JSONUtil.parseObj(map).toString();
|
||||||
} else if (value instanceof Collection) {
|
} else if (value instanceof Collection) {
|
||||||
final Collection<?> coll = (Collection<?>) value;
|
final Collection<?> coll = (Collection<?>) value;
|
||||||
return new JSONArray(coll).toString();
|
return JSONUtil.parseArray(coll).toString();
|
||||||
} else if (ArrayUtil.isArray(value)) {
|
} else if (ArrayUtil.isArray(value)) {
|
||||||
return new JSONArray(value).toString();
|
return JSONUtil.parseArray(value).toString();
|
||||||
} else {
|
} else {
|
||||||
return quote(value.toString());
|
return quote(value.toString());
|
||||||
}
|
}
|
||||||
|
@ -17,16 +17,12 @@
|
|||||||
package org.dromara.hutool.json;
|
package org.dromara.hutool.json;
|
||||||
|
|
||||||
import org.dromara.hutool.core.collection.CollUtil;
|
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.ConvertUtil;
|
||||||
import org.dromara.hutool.core.convert.impl.ArrayConverter;
|
import org.dromara.hutool.core.convert.impl.ArrayConverter;
|
||||||
import org.dromara.hutool.core.lang.Validator;
|
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.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.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 org.dromara.hutool.json.writer.JSONWriter;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@ -43,7 +39,7 @@ import java.util.function.Predicate;
|
|||||||
*
|
*
|
||||||
* @author looly
|
* @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;
|
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;
|
public static final int DEFAULT_CAPACITY = 10;
|
||||||
|
|
||||||
/**
|
|
||||||
* 持有原始数据的List
|
|
||||||
*/
|
|
||||||
private List<Object> rawList;
|
|
||||||
/**
|
/**
|
||||||
* 配置项
|
* 配置项
|
||||||
*/
|
*/
|
||||||
private JSONConfig config;
|
private JSONConfig config;
|
||||||
/**
|
|
||||||
* 对象转换和包装,用于将Java对象和值转换为JSON值
|
|
||||||
*/
|
|
||||||
private JSONValueMapper valueMapper;
|
|
||||||
|
|
||||||
// region Constructors
|
// region ----- Constructors
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造<br>
|
* 构造<br>
|
||||||
@ -105,66 +93,8 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
|
|||||||
* @since 4.1.19
|
* @since 4.1.19
|
||||||
*/
|
*/
|
||||||
public JSONArray(final int initialCapacity, final JSONConfig config) {
|
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.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
|
// endregion
|
||||||
|
|
||||||
@ -173,54 +103,21 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
|
|||||||
return this.config;
|
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
|
@Override
|
||||||
public Object get(final int index) {
|
public JSON get(final int index) {
|
||||||
Object value = this.rawList.get(index);
|
return this.raw.get(index);
|
||||||
if(value instanceof JSONPrimitive){
|
|
||||||
value = ((JSONPrimitive) value).getValue();
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getObj(final Integer index, final Object defaultValue) {
|
public Object getObj(final Integer index, final Object defaultValue) {
|
||||||
return (index < 0 || index >= this.size()) ? defaultValue : this.rawList.get(index);
|
final Object value;
|
||||||
}
|
final JSON json = get(index);
|
||||||
|
if(json instanceof JSONPrimitive){
|
||||||
/**
|
value = ((JSONPrimitive) json).getValue();
|
||||||
* Append an object value. This increases the array's length by one. <br>
|
}else {
|
||||||
* 加入元素,数组长度+1,等同于 {@link JSONArray#add(Object)}
|
value = json;
|
||||||
*
|
}
|
||||||
* @param value 值,可以是: Boolean, Double, Integer, JSONArray, JSONObject, Long, or String, or the JSONNull.NULL。
|
return ObjUtil.defaultIfNull(value, defaultValue);
|
||||||
* @return this.
|
|
||||||
* @see #set(Object)
|
|
||||||
*/
|
|
||||||
public JSONArray put(final Object value) {
|
|
||||||
return set(value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -232,21 +129,7 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
|
|||||||
* @since 5.2.5
|
* @since 5.2.5
|
||||||
*/
|
*/
|
||||||
public JSONArray set(final Object value) {
|
public JSONArray set(final Object value) {
|
||||||
this.add(value);
|
this.add(config.getConverter().convert(JSON.class, 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);
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,36 +151,10 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
|
|||||||
return jo;
|
return jo;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
final int prime = 31;
|
|
||||||
int result = 1;
|
|
||||||
result = prime * result + ((rawList == null) ? 0 : rawList.hashCode());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(final Object obj) {
|
public Iterator<JSON> iterator() {
|
||||||
if (this == obj) {
|
return raw.iterator();
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -309,7 +166,7 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
|
|||||||
* @param type JSON类型
|
* @param type JSON类型
|
||||||
*/
|
*/
|
||||||
public <T extends JSON> Iterable<T> jsonIter(final Class<T> type) {
|
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>() {
|
return () -> new Iterator<T>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean hasNext() {
|
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
|
@Override
|
||||||
@SuppressWarnings({"unchecked"})
|
@SuppressWarnings({"unchecked"})
|
||||||
public <T> T[] toArray(final T[] a) {
|
public <T> T[] toArray(final T[] a) {
|
||||||
@ -354,78 +191,29 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean add(final Object e) {
|
public boolean addAll(final int index, final Collection<? extends JSON> c) {
|
||||||
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) {
|
|
||||||
if (CollUtil.isEmpty(c)) {
|
if (CollUtil.isEmpty(c)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (final Object obj : c) {
|
final List<JSON> list = new ArrayList<>(c.size());
|
||||||
this.add(obj);
|
for (final JSON json : c) {
|
||||||
}
|
if (null == json && config.isIgnoreNullValue()) {
|
||||||
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()) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
this.add(index);
|
list.add(json);
|
||||||
list.add(valueMapper.map(object));
|
|
||||||
}
|
}
|
||||||
return rawList.addAll(index, list);
|
return raw.addAll(index, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public boolean removeAll(final Collection<?> c) {
|
* 加入或者替换JSONArray中指定Index的值,如果index大于JSONArray的长度,将在指定index设置值,之前的位置填充JSONNull.Null
|
||||||
return this.rawList.removeAll(c);
|
*
|
||||||
}
|
* @param index 位置
|
||||||
|
* @param element 值对象. 可以是以下类型: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or the JSONNull.NULL.
|
||||||
@Override
|
* @return 替换的值,即之前的值
|
||||||
public boolean retainAll(final Collection<?> c) {
|
*/
|
||||||
return this.rawList.retainAll(c);
|
public JSON setValue(final int index, final Object element) {
|
||||||
}
|
return set(index, config.getConverter().convert(JSON.class, element));
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clear() {
|
|
||||||
this.rawList.clear();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -436,29 +224,7 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
|
|||||||
* @return 替换的值,即之前的值
|
* @return 替换的值,即之前的值
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Object set(final int index, final Object element) {
|
public JSON set(final int index, final JSON 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<MutableEntry<Integer, Object>> filter) {
|
|
||||||
// 添加前置过滤,通过MutablePair实现过滤、修改键值对等
|
|
||||||
if (null != filter) {
|
|
||||||
final MutableEntry<Integer, Object> pair = new MutableEntry<>(index, element);
|
|
||||||
if (filter.test(pair)) {
|
|
||||||
// 使用修改后的值
|
|
||||||
element = pair.getValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 越界则追加到指定位置
|
// 越界则追加到指定位置
|
||||||
if (index >= size()) {
|
if (index >= size()) {
|
||||||
add(index, element);
|
add(index, element);
|
||||||
@ -467,11 +233,11 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
|
|||||||
if (null == element && config.isIgnoreNullValue()) {
|
if (null == element && config.isIgnoreNullValue()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return this.rawList.set(index, valueMapper.map(element));
|
return this.raw.set(index, element);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void add(int index, final Object element) {
|
public void add(int index, final JSON element) {
|
||||||
if (null == element && config.isIgnoreNullValue()) {
|
if (null == element && config.isIgnoreNullValue()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -479,7 +245,7 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
|
|||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
index = 0;
|
index = 0;
|
||||||
}
|
}
|
||||||
this.rawList.add(index, valueMapper.map(element));
|
this.raw.add(index, element);
|
||||||
} else {
|
} else {
|
||||||
// issue#3286, 如果用户指定的index太大,容易造成Java heap space错误。
|
// issue#3286, 如果用户指定的index太大,容易造成Java heap space错误。
|
||||||
if (!config.isIgnoreNullValue()) {
|
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数组
|
* 转为Bean数组
|
||||||
*
|
*
|
||||||
@ -569,45 +310,15 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(final JSONWriter writer) throws JSONException {
|
public void write(final JSONWriter writer) throws JSONException {
|
||||||
final JSONWriter copyWriter = writer.copyOfSub();
|
writer.beginArray();
|
||||||
copyWriter.beginArray();
|
CollUtil.forEach(this, (index, value) -> writer.writeField(new MutableEntry<>(index, value)));
|
||||||
CollUtil.forEach(this, (value, index) -> copyWriter.writeField(new MutableEntry<>(index, value)));
|
writer.end();
|
||||||
copyWriter.end();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object clone() throws CloneNotSupportedException {
|
public Object clone() throws CloneNotSupportedException {
|
||||||
final JSONArray clone = (JSONArray) super.clone();
|
final JSONArray clone = (JSONArray) super.clone();
|
||||||
clone.config = this.config;
|
clone.config = this.config;
|
||||||
clone.valueMapper = this.valueMapper;
|
|
||||||
clone.rawList = ObjUtil.clone(this.rawList);
|
|
||||||
return clone;
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ public interface JSONGetter<K> extends TypeGetter<K> {
|
|||||||
if (object instanceof JSON) {
|
if (object instanceof JSON) {
|
||||||
return (JSONArray) object;
|
return (JSONArray) object;
|
||||||
}
|
}
|
||||||
return new JSONArray(object, config());
|
return JSONUtil.parseArray(object, config());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,7 +25,6 @@ import org.dromara.hutool.core.map.MapUtil;
|
|||||||
import org.dromara.hutool.core.map.MapWrapper;
|
import org.dromara.hutool.core.map.MapWrapper;
|
||||||
import org.dromara.hutool.core.text.StrUtil;
|
import org.dromara.hutool.core.text.StrUtil;
|
||||||
import org.dromara.hutool.core.util.ObjUtil;
|
import org.dromara.hutool.core.util.ObjUtil;
|
||||||
import org.dromara.hutool.json.mapper.JSONValueMapper;
|
|
||||||
import org.dromara.hutool.json.writer.JSONWriter;
|
import org.dromara.hutool.json.writer.JSONWriter;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -53,10 +52,6 @@ public class JSONObject extends MapWrapper<String, JSON> implements JSON, JSONGe
|
|||||||
* 配置项
|
* 配置项
|
||||||
*/
|
*/
|
||||||
private final JSONConfig config;
|
private final JSONConfig config;
|
||||||
/**
|
|
||||||
* 对象转换和包装,用于将Java对象和值转换为JSON值
|
|
||||||
*/
|
|
||||||
private final JSONValueMapper valueMapper;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造,初始容量为 {@link #DEFAULT_CAPACITY},KEY有序
|
* 构造,初始容量为 {@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) {
|
public JSONObject(final int capacity, final JSONConfig config) {
|
||||||
super(InternalJSONUtil.createRawMap(capacity, config));
|
super(InternalJSONUtil.createRawMap(capacity, config));
|
||||||
this.config = ObjUtil.defaultIfNull(config, JSONConfig::of);
|
this.config = ObjUtil.defaultIfNull(config, JSONConfig::of);
|
||||||
this.valueMapper = JSONValueMapper.of(this.config);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -94,10 +88,9 @@ public class JSONObject extends MapWrapper<String, JSON> implements JSON, JSONGe
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(final JSONWriter writer) throws JSONException {
|
public void write(final JSONWriter writer) throws JSONException {
|
||||||
final JSONWriter jsonWriter = writer.copyOfSub();
|
writer.beginObj();
|
||||||
jsonWriter.beginObj();
|
this.forEach((key, value) -> writer.writeField(new MutableEntry<>(key, value)));
|
||||||
this.forEach((key, value) -> jsonWriter.writeField(new MutableEntry<>(key, value)));
|
writer.end();
|
||||||
jsonWriter.end();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// region ----- get
|
// region ----- get
|
||||||
@ -225,7 +218,7 @@ public class JSONObject extends MapWrapper<String, JSON> implements JSON, JSONGe
|
|||||||
* @throws JSONException 值是无穷数字抛出此异常
|
* @throws JSONException 值是无穷数字抛出此异常
|
||||||
*/
|
*/
|
||||||
public JSONObject set(final String key, final Object value) 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;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,8 +23,7 @@ import org.dromara.hutool.core.lang.mutable.MutableEntry;
|
|||||||
import org.dromara.hutool.core.reflect.TypeReference;
|
import org.dromara.hutool.core.reflect.TypeReference;
|
||||||
import org.dromara.hutool.core.text.StrUtil;
|
import org.dromara.hutool.core.text.StrUtil;
|
||||||
import org.dromara.hutool.core.util.ObjUtil;
|
import org.dromara.hutool.core.util.ObjUtil;
|
||||||
import org.dromara.hutool.json.convert.JSONConverter;
|
import org.dromara.hutool.json.mapper.JSONValueMapper;
|
||||||
import org.dromara.hutool.json.mapper.JSONObjectMapper;
|
|
||||||
import org.dromara.hutool.json.writer.JSONWriter;
|
import org.dromara.hutool.json.writer.JSONWriter;
|
||||||
import org.dromara.hutool.json.writer.ValueWriter;
|
import org.dromara.hutool.json.writer.ValueWriter;
|
||||||
import org.dromara.hutool.json.writer.ValueWriterManager;
|
import org.dromara.hutool.json.writer.ValueWriterManager;
|
||||||
@ -46,6 +45,7 @@ import java.util.function.Predicate;
|
|||||||
public class JSONUtil {
|
public class JSONUtil {
|
||||||
|
|
||||||
// region ----- of
|
// region ----- of
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建JSONObject
|
* 创建JSONObject
|
||||||
*
|
*
|
||||||
@ -88,6 +88,7 @@ public class JSONUtil {
|
|||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// region ----- parse
|
// region ----- parse
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JSON字符串转JSONObject对象<br>
|
* JSON字符串转JSONObject对象<br>
|
||||||
* 此方法会忽略空值,但是对JSON字符串不影响
|
* 此方法会忽略空值,但是对JSON字符串不影响
|
||||||
@ -99,18 +100,6 @@ public class JSONUtil {
|
|||||||
return parseObj(obj, JSONConfig.of(), null);
|
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字符串转JSONObject对象<br>
|
||||||
* 此方法会忽略空值,但是对JSON字符串不影响
|
* 此方法会忽略空值,但是对JSON字符串不影响
|
||||||
@ -133,9 +122,7 @@ public class JSONUtil {
|
|||||||
* @return JSONObject
|
* @return JSONObject
|
||||||
*/
|
*/
|
||||||
public static JSONObject parseObj(final Object obj, final JSONConfig config, final Predicate<MutableEntry<Object, Object>> predicate) {
|
public static JSONObject parseObj(final Object obj, final JSONConfig config, final Predicate<MutableEntry<Object, Object>> predicate) {
|
||||||
final JSONObject jsonObject = new JSONObject(config);
|
return (JSONObject) parse(obj, config, predicate);
|
||||||
JSONObjectMapper.of(obj, predicate).mapTo(jsonObject);
|
|
||||||
return jsonObject;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -146,7 +133,7 @@ public class JSONUtil {
|
|||||||
* @since 3.0.8
|
* @since 3.0.8
|
||||||
*/
|
*/
|
||||||
public static JSONArray parseArray(final Object arrayOrCollection) {
|
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
|
* @since 5.3.1
|
||||||
*/
|
*/
|
||||||
public static JSONArray parseArray(final Object arrayOrCollection, final JSONConfig config) {
|
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>
|
* <li>Bean对象:转为JSONObject</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @param obj 对象
|
* @param obj 对象
|
||||||
* @param config JSON配置,{@code null}使用默认配置
|
* @param config JSON配置,{@code null}使用默认配置
|
||||||
* @return JSON(JSONObject or JSONArray)
|
* @return JSON(JSONObject or JSONArray)
|
||||||
*/
|
*/
|
||||||
public static JSON parse(final Object obj, final JSONConfig config) {
|
public static JSON parse(final Object obj, final JSONConfig config) {
|
||||||
if (null == config) {
|
return parse(obj, config, null);
|
||||||
return JSONConverter.INSTANCE.toJSON(obj);
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换对象为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 JSON(JSONObject 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异常
|
* @throws IORuntimeException IO异常
|
||||||
*/
|
*/
|
||||||
public static JSON readJSON(final File file, final Charset charset) throws IORuntimeException {
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,14 +16,11 @@
|
|||||||
|
|
||||||
package org.dromara.hutool.json.convert;
|
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.BeanUtil;
|
||||||
import org.dromara.hutool.core.bean.copier.BeanCopier;
|
import org.dromara.hutool.core.bean.copier.BeanCopier;
|
||||||
import org.dromara.hutool.core.convert.*;
|
import org.dromara.hutool.core.convert.*;
|
||||||
import org.dromara.hutool.core.convert.impl.DateConverter;
|
import org.dromara.hutool.core.convert.impl.DateConverter;
|
||||||
import org.dromara.hutool.core.convert.impl.TemporalAccessorConverter;
|
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.ConstructorUtil;
|
||||||
import org.dromara.hutool.core.reflect.TypeReference;
|
import org.dromara.hutool.core.reflect.TypeReference;
|
||||||
import org.dromara.hutool.core.reflect.TypeUtil;
|
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.text.StrUtil;
|
||||||
import org.dromara.hutool.core.util.ObjUtil;
|
import org.dromara.hutool.core.util.ObjUtil;
|
||||||
import org.dromara.hutool.json.*;
|
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.JSONParser;
|
||||||
import org.dromara.hutool.json.reader.JSONTokener;
|
import org.dromara.hutool.json.reader.JSONTokener;
|
||||||
import org.dromara.hutool.json.serializer.JSONDeserializer;
|
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.SerializerManager;
|
||||||
import org.dromara.hutool.json.serializer.SimpleJSONContext;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.time.temporal.TemporalAccessor;
|
import java.time.temporal.TemporalAccessor;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JSON转换器,实现Object对象转换为{@link JSON},支持的对象:
|
* JSON转换器,实现Object对象转换为{@link JSON},支持的对象:
|
||||||
@ -139,47 +133,12 @@ public class JSONConverter implements Converter, Serializable {
|
|||||||
* @return 转换后的对象
|
* @return 转换后的对象
|
||||||
* @throws JSONException 转换异常
|
* @throws JSONException 转换异常
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
public JSON toJSON(final Object obj) throws JSONException {
|
||||||
public JSON toJSON(Object obj) throws JSONException {
|
|
||||||
if (null == obj) {
|
if (null == obj) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj instanceof Optional) {
|
return JSONValueMapper.of(config, null).map(obj);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -231,7 +190,7 @@ public class JSONConverter implements Converter, Serializable {
|
|||||||
|
|
||||||
// 当目标类型不确定时,返回原JSON
|
// 当目标类型不确定时,返回原JSON
|
||||||
final Class<T> rawType = (Class<T>) TypeUtil.getClass(targetType);
|
final Class<T> rawType = (Class<T>) TypeUtil.getClass(targetType);
|
||||||
if (null == rawType) {
|
if (null == rawType || rawType.isInstance(json)) {
|
||||||
return (T) json;
|
return (T) json;
|
||||||
//throw new JSONException("Can not get class from type: {}", targetType);
|
//throw new JSONException("Can not get class from type: {}", targetType);
|
||||||
}
|
}
|
||||||
|
@ -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.JWTSignerUtil;
|
||||||
import org.dromara.hutool.json.jwt.signers.NoneJWTSigner;
|
import org.dromara.hutool.json.jwt.signers.NoneJWTSigner;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.security.Key;
|
import java.security.Key;
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
@ -299,7 +300,7 @@ public class JWT implements RegisteredPayload<JWT> {
|
|||||||
* @throws ValidateException 传入的类型不匹配payload类型
|
* @throws ValidateException 传入的类型不匹配payload类型
|
||||||
* @since 6.0.0
|
* @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);
|
return getPayload().getClaimsJson().get(propertyName, propertyType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,15 +20,11 @@ import org.dromara.hutool.core.array.ArrayUtil;
|
|||||||
import org.dromara.hutool.core.collection.iter.ArrayIter;
|
import org.dromara.hutool.core.collection.iter.ArrayIter;
|
||||||
import org.dromara.hutool.core.io.IoUtil;
|
import org.dromara.hutool.core.io.IoUtil;
|
||||||
import org.dromara.hutool.core.lang.mutable.MutableEntry;
|
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.JSONArray;
|
||||||
import org.dromara.hutool.json.JSONConfig;
|
import org.dromara.hutool.json.JSONConfig;
|
||||||
import org.dromara.hutool.json.JSONException;
|
import org.dromara.hutool.json.JSONException;
|
||||||
import org.dromara.hutool.json.reader.JSONParser;
|
import org.dromara.hutool.json.reader.JSONParser;
|
||||||
import org.dromara.hutool.json.reader.JSONTokener;
|
import org.dromara.hutool.json.reader.JSONTokener;
|
||||||
import org.dromara.hutool.json.serializer.JSONSerializer;
|
|
||||||
import org.dromara.hutool.json.serializer.SerializerManager;
|
|
||||||
import org.dromara.hutool.json.serializer.SimpleJSONContext;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
@ -50,7 +46,7 @@ import java.util.function.Predicate;
|
|||||||
* @author looly
|
* @author looly
|
||||||
* @since 6.0.0
|
* @since 6.0.0
|
||||||
*/
|
*/
|
||||||
public class JSONArrayMapper {
|
class JSONArrayMapper {
|
||||||
/**
|
/**
|
||||||
* 创建ArrayMapper
|
* 创建ArrayMapper
|
||||||
*
|
*
|
||||||
@ -88,20 +84,10 @@ public class JSONArrayMapper {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 自定义序列化
|
|
||||||
final JSONSerializer<Object> serializer = SerializerManager.getInstance().getSerializer(source.getClass());
|
|
||||||
if (null != serializer) {
|
|
||||||
serializer.serialize(source, new SimpleJSONContext(jsonArray));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (source instanceof JSONTokener) {
|
if (source instanceof JSONTokener) {
|
||||||
mapFromTokener((JSONTokener) source, JSONConfig.of(), jsonArray);
|
mapFromTokener((JSONTokener) source, JSONConfig.of(), jsonArray);
|
||||||
}if (source instanceof JSONParser) {
|
}if (source instanceof JSONParser) {
|
||||||
((JSONParser)source).parseTo(jsonArray);
|
((JSONParser)source).parseTo(jsonArray);
|
||||||
} else if (source instanceof CharSequence) {
|
|
||||||
// JSON字符串
|
|
||||||
mapFromStr((CharSequence) source, jsonArray);
|
|
||||||
} else if (source instanceof Reader) {
|
} else if (source instanceof Reader) {
|
||||||
mapFromTokener(new JSONTokener((Reader) source), jsonArray.config(), jsonArray);
|
mapFromTokener(new JSONTokener((Reader) source), jsonArray.config(), jsonArray);
|
||||||
} else if (source instanceof InputStream) {
|
} else if (source instanceof InputStream) {
|
||||||
@ -114,7 +100,7 @@ public class JSONArrayMapper {
|
|||||||
// https://github.com/dromara/hutool/issues/2369
|
// https://github.com/dromara/hutool/issues/2369
|
||||||
// 非标准的二进制流,则按照普通数组对待
|
// 非标准的二进制流,则按照普通数组对待
|
||||||
for (final byte b : bytesSource) {
|
for (final byte b : bytesSource) {
|
||||||
jsonArray.add(b);
|
jsonArray.set(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -143,28 +129,16 @@ public class JSONArrayMapper {
|
|||||||
if (predicate.test(entry)) {
|
if (predicate.test(entry)) {
|
||||||
// 使用修改后的键值对
|
// 使用修改后的键值对
|
||||||
next = entry.getValue();
|
next = entry.getValue();
|
||||||
jsonArray.add(next);
|
jsonArray.set(next);
|
||||||
}
|
}
|
||||||
}else {
|
}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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化
|
* 初始化
|
||||||
*
|
*
|
||||||
|
@ -27,11 +27,6 @@ import org.dromara.hutool.core.text.StrUtil;
|
|||||||
import org.dromara.hutool.json.*;
|
import org.dromara.hutool.json.*;
|
||||||
import org.dromara.hutool.json.reader.JSONParser;
|
import org.dromara.hutool.json.reader.JSONParser;
|
||||||
import org.dromara.hutool.json.reader.JSONTokener;
|
import org.dromara.hutool.json.reader.JSONTokener;
|
||||||
import org.dromara.hutool.json.serializer.JSONSerializer;
|
|
||||||
import org.dromara.hutool.json.serializer.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.InputStream;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
@ -55,9 +50,8 @@ import java.util.function.Predicate;
|
|||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @author looly
|
* @author looly
|
||||||
* @since 5.8.0
|
|
||||||
*/
|
*/
|
||||||
public class JSONObjectMapper {
|
class JSONObjectMapper {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建ObjectMapper
|
* 创建ObjectMapper
|
||||||
@ -96,13 +90,6 @@ public class JSONObjectMapper {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 自定义序列化
|
|
||||||
final JSONSerializer<Object> serializer = SerializerManager.getInstance().getSerializer(source.getClass());
|
|
||||||
if (null != serializer) {
|
|
||||||
serializer.serialize(source, new SimpleJSONContext(jsonObject));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (source instanceof JSONArray) {
|
if (source instanceof JSONArray) {
|
||||||
// 不支持集合类型转换为JSONObject
|
// 不支持集合类型转换为JSONObject
|
||||||
throw new JSONException("Unsupported type [{}] to JSONObject!", source.getClass());
|
throw new JSONException("Unsupported type [{}] to JSONObject!", source.getClass());
|
||||||
@ -122,9 +109,6 @@ public class JSONObjectMapper {
|
|||||||
} else if (source instanceof Map.Entry) {
|
} else if (source instanceof Map.Entry) {
|
||||||
final Map.Entry entry = (Map.Entry) source;
|
final Map.Entry entry = (Map.Entry) source;
|
||||||
jsonObject.set(ConvertUtil.toStr(entry.getKey()), entry.getValue());
|
jsonObject.set(ConvertUtil.toStr(entry.getKey()), entry.getValue());
|
||||||
} else if (source instanceof CharSequence) {
|
|
||||||
// 可能为JSON字符串
|
|
||||||
mapFromStr((CharSequence) source, jsonObject);
|
|
||||||
} else if (source instanceof Reader) {
|
} else if (source instanceof Reader) {
|
||||||
mapFromTokener(new JSONTokener((Reader) source), jsonObject.config(), jsonObject);
|
mapFromTokener(new JSONTokener((Reader) source), jsonObject.config(), jsonObject);
|
||||||
} else if (source instanceof InputStream) {
|
} 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}转换
|
* 从{@link JSONTokener}转换
|
||||||
*
|
*
|
||||||
|
@ -18,10 +18,23 @@ package org.dromara.hutool.json.mapper;
|
|||||||
|
|
||||||
import org.dromara.hutool.core.array.ArrayUtil;
|
import org.dromara.hutool.core.array.ArrayUtil;
|
||||||
import org.dromara.hutool.core.exception.ExceptionUtil;
|
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.*;
|
||||||
|
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.writer.ValueWriterManager;
|
||||||
|
import org.dromara.hutool.json.xml.JSONXMLParser;
|
||||||
|
import org.dromara.hutool.json.xml.ParseConfig;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 对象和JSON值映射器,用于转换对象为JSON对象中的值<br>
|
* 对象和JSON值映射器,用于转换对象为JSON对象中的值<br>
|
||||||
@ -45,22 +58,45 @@ public class JSONValueMapper implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* 创建ObjectMapper
|
* 创建ObjectMapper
|
||||||
*
|
*
|
||||||
* @param jsonConfig 来源对象
|
* @param jsonConfig 来源对象
|
||||||
|
* @param predicate 键值对过滤编辑器,可以通过实现此接口,完成解析前对键值对的过滤和修改操作,{@link Predicate#test(Object)}为{@code true}保留
|
||||||
* @return ObjectMapper
|
* @return ObjectMapper
|
||||||
*/
|
*/
|
||||||
public static JSONValueMapper of(final JSONConfig jsonConfig) {
|
public static JSONValueMapper of(final JSONConfig jsonConfig, final Predicate<MutableEntry<Object, Object>> predicate) {
|
||||||
return new JSONValueMapper(jsonConfig);
|
return new JSONValueMapper(jsonConfig, predicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final JSONConfig jsonConfig;
|
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.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>
|
* <li>其它 =》 尝试包装为JSONObject,否则返回{@code null}</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @param object 被映射的对象
|
* @param obj 被映射的对象
|
||||||
* @return 映射后的值,null表示此值需被忽略
|
* @return 映射后的值,null表示此值需被忽略
|
||||||
*/
|
*/
|
||||||
public JSON map(final Object object) {
|
public JSON map(Object obj) {
|
||||||
if(null == object || object instanceof JSON){
|
if (null == obj) {
|
||||||
return (JSON) object;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(null != ValueWriterManager.getInstance().get(object)){
|
if (obj instanceof Optional) {
|
||||||
return new JSONPrimitive(object, jsonConfig);
|
obj = ((Optional<?>) obj).orElse(null);
|
||||||
|
} else if (obj instanceof Opt) {
|
||||||
|
obj = ((Opt<?>) obj).getOrNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (object instanceof CharSequence
|
if (obj instanceof JSON) {
|
||||||
// || ObjUtil.isBasicType(object)) {
|
return (JSON) obj;
|
||||||
// return new JSONPrimitive(object, jsonConfig);
|
}
|
||||||
// }
|
|
||||||
|
// 自定义序列化
|
||||||
|
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 {
|
try {
|
||||||
// JSONArray
|
// 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);
|
final JSONArray jsonArray = new JSONArray(jsonConfig);
|
||||||
JSONArrayMapper.of(object, null).mapTo(jsonArray);
|
JSONArrayMapper.of(obj, predicate).mapTo(jsonArray);
|
||||||
return jsonArray;
|
return jsonArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 默认按照JSONObject对待
|
// 默认按照JSONObject对待
|
||||||
final JSONObject jsonObject = new JSONObject(jsonConfig);
|
final JSONObject jsonObject = new JSONObject(jsonConfig);
|
||||||
JSONObjectMapper.of(object, null).mapTo(jsonObject);
|
JSONObjectMapper.of(obj, predicate).mapTo(jsonObject);
|
||||||
return jsonObject;
|
return jsonObject;
|
||||||
} catch (final Exception exception) {
|
} catch (final Exception exception) {
|
||||||
if(jsonConfig.isIgnoreError()){
|
if (jsonConfig.isIgnoreError()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
throw ExceptionUtil.wrap(exception, JSONException.class);
|
throw ExceptionUtil.wrap(exception, JSONException.class);
|
||||||
|
@ -232,13 +232,13 @@ public class JSONParser {
|
|||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// ,value or value
|
// ,value or value
|
||||||
Object value = nextJSON(CharUtil.COMMA == c ? tokener.nextClean() : c);
|
JSON value = nextJSON(CharUtil.COMMA == c ? tokener.nextClean() : c);
|
||||||
if (null != predicate) {
|
if (null != predicate) {
|
||||||
// 使用过滤器
|
// 使用过滤器
|
||||||
final MutableEntry<Object, Object> entry = MutableEntry.of(jsonArray.size(), value);
|
final MutableEntry<Object, Object> entry = MutableEntry.of(jsonArray.size(), value);
|
||||||
if (predicate.test(entry)) {
|
if (predicate.test(entry)) {
|
||||||
// 使用修改后的键值对
|
// 使用修改后的键值对
|
||||||
value = entry.getValue();
|
value = (JSON) entry.getValue();
|
||||||
jsonArray.add(value);
|
jsonArray.add(value);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -161,11 +161,11 @@ public class SerializerManager {
|
|||||||
* @param bean 对象
|
* @param bean 对象
|
||||||
* @return JSONSerializer
|
* @return JSONSerializer
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"rawtypes"})
|
@SuppressWarnings({"unchecked"})
|
||||||
public JSONSerializer<?> getSerializer(final Object bean) {
|
public JSONSerializer<Object> getSerializer(final Object bean) {
|
||||||
for (final MatcherJSONSerializer serializer : this.serializerSet) {
|
for (final MatcherJSONSerializer<?> serializer : this.serializerSet) {
|
||||||
if (serializer.match(bean, null)) {
|
if (serializer.match(bean, null)) {
|
||||||
return serializer;
|
return (JSONSerializer<Object>) serializer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -121,16 +121,6 @@ public class JSONWriter implements Appendable, Flushable, Closeable {
|
|||||||
return this.config;
|
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写出开始,默认写出"{"
|
* JSONObject写出开始,默认写出"{"
|
||||||
*
|
*
|
||||||
@ -141,6 +131,7 @@ public class JSONWriter implements Appendable, Flushable, Closeable {
|
|||||||
append(CharUtil.DELIM_START);
|
append(CharUtil.DELIM_START);
|
||||||
arrayMode = false;
|
arrayMode = false;
|
||||||
needSeparator = false;
|
needSeparator = false;
|
||||||
|
indent += indentFactor;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,6 +145,7 @@ public class JSONWriter implements Appendable, Flushable, Closeable {
|
|||||||
append(CharUtil.BRACKET_START);
|
append(CharUtil.BRACKET_START);
|
||||||
arrayMode = true;
|
arrayMode = true;
|
||||||
needSeparator = false;
|
needSeparator = false;
|
||||||
|
indent += indentFactor;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,6 +156,8 @@ public class JSONWriter implements Appendable, Flushable, Closeable {
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("resource")
|
@SuppressWarnings("resource")
|
||||||
public JSONWriter end() {
|
public JSONWriter end() {
|
||||||
|
// 结束子缩进
|
||||||
|
indent -= indentFactor;
|
||||||
// 换行缩进
|
// 换行缩进
|
||||||
writeLF().writeSpace(indent);
|
writeLF().writeSpace(indent);
|
||||||
append(arrayMode ? CharUtil.BRACKET_END : CharUtil.DELIM_END);
|
append(arrayMode ? CharUtil.BRACKET_END : CharUtil.DELIM_END);
|
||||||
@ -215,7 +209,7 @@ public class JSONWriter implements Appendable, Flushable, Closeable {
|
|||||||
append(CharUtil.COMMA);
|
append(CharUtil.COMMA);
|
||||||
}
|
}
|
||||||
// 换行缩进
|
// 换行缩进
|
||||||
writeLF().writeSpace(indentFactor + indent);
|
writeLF().writeSpace(indent);
|
||||||
return writeRaw(InternalJSONUtil.quote(key));
|
return writeRaw(InternalJSONUtil.quote(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -346,7 +340,7 @@ public class JSONWriter implements Appendable, Flushable, Closeable {
|
|||||||
}
|
}
|
||||||
// 换行缩进
|
// 换行缩进
|
||||||
//noinspection resource
|
//noinspection resource
|
||||||
writeLF().writeSpace(indentFactor + indent);
|
writeLF().writeSpace(indent);
|
||||||
} else {
|
} else {
|
||||||
//noinspection resource
|
//noinspection resource
|
||||||
append(CharUtil.COLON).writeSpace(1);
|
append(CharUtil.COLON).writeSpace(1);
|
||||||
|
@ -100,7 +100,7 @@ public class ValueWriterManager {
|
|||||||
private static void registerDefault() {
|
private static void registerDefault() {
|
||||||
final ValueWriterManager manager = SingletonHolder.INSTANCE;
|
final ValueWriterManager manager = SingletonHolder.INSTANCE;
|
||||||
// JDK对象最后判断
|
// JDK对象最后判断
|
||||||
manager.register(JdkValueWriter.INSTANCE);
|
// manager.register(JdkValueWriter.INSTANCE);
|
||||||
manager.register(NumberValueWriter.INSTANCE);
|
manager.register(NumberValueWriter.INSTANCE);
|
||||||
manager.register(DateValueWriter.INSTANCE);
|
manager.register(DateValueWriter.INSTANCE);
|
||||||
manager.register(BooleanValueWriter.INSTANCE);
|
manager.register(BooleanValueWriter.INSTANCE);
|
||||||
|
@ -23,6 +23,7 @@ import org.dromara.hutool.core.text.escape.EscapeUtil;
|
|||||||
import org.dromara.hutool.json.JSONArray;
|
import org.dromara.hutool.json.JSONArray;
|
||||||
import org.dromara.hutool.json.JSONException;
|
import org.dromara.hutool.json.JSONException;
|
||||||
import org.dromara.hutool.json.JSONObject;
|
import org.dromara.hutool.json.JSONObject;
|
||||||
|
import org.dromara.hutool.json.JSONUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JSON转XML字符串工具
|
* JSON转XML字符串工具
|
||||||
@ -78,7 +79,7 @@ public class JSONXMLSerializer {
|
|||||||
// Loop thru the keys.
|
// Loop thru the keys.
|
||||||
((JSONObject) object).forEach((key, value) -> {
|
((JSONObject) object).forEach((key, value) -> {
|
||||||
if (ArrayUtil.isArray(value)) {
|
if (ArrayUtil.isArray(value)) {
|
||||||
value = new JSONArray(value);
|
value = JSONUtil.parseArray(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emit content in body
|
// Emit content in body
|
||||||
@ -119,7 +120,7 @@ public class JSONXMLSerializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ArrayUtil.isArray(object)) {
|
if (ArrayUtil.isArray(object)) {
|
||||||
object = new JSONArray(object);
|
object = JSONUtil.parseArray(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (object instanceof JSONArray) {
|
if (object instanceof JSONArray) {
|
||||||
|
@ -51,7 +51,7 @@ public class Issue3274Test {
|
|||||||
|
|
||||||
Gender(final String enum_name, final String en_Us, final String zh_CN) {
|
Gender(final String enum_name, final String en_Us, final String zh_CN) {
|
||||||
this.enum_name = enum_name;
|
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 + "\"}]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
package org.dromara.hutool.json;
|
package org.dromara.hutool.json;
|
||||||
|
|
||||||
import org.dromara.hutool.core.text.StrUtil;
|
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.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
@ -27,12 +27,11 @@ public class IssueI9DX5HTest {
|
|||||||
@Test
|
@Test
|
||||||
void xmlToJSONTest() {
|
void xmlToJSONTest() {
|
||||||
final String xml = "<GoodMsg>你好</GoodMsg>";
|
final String xml = "<GoodMsg>你好</GoodMsg>";
|
||||||
final JSONObjectMapper mapper = JSONObjectMapper.of(xml, entry -> {
|
final JSONValueMapper mapper = JSONValueMapper.of(JSONConfig.of(), entry -> {
|
||||||
entry.setKey(StrUtil.toUnderlineCase((CharSequence) entry.getKey()));
|
entry.setKey(StrUtil.toUnderlineCase((CharSequence) entry.getKey()));
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
final JSONObject jsonObject = new JSONObject();
|
final JSONObject jsonObject = (JSONObject) mapper.map(xml);
|
||||||
mapper.mapTo(jsonObject);
|
|
||||||
|
|
||||||
Assertions.assertEquals("{\"good_msg\":\"你好\"}", jsonObject.toString());
|
Assertions.assertEquals("{\"good_msg\":\"你好\"}", jsonObject.toString());
|
||||||
}
|
}
|
||||||
|
@ -48,11 +48,11 @@ public class JSONArrayTest {
|
|||||||
// JSONObject实现了Iterable接口,可以转换为JSONArray
|
// JSONObject实现了Iterable接口,可以转换为JSONArray
|
||||||
final JSONObject jsonObject = new JSONObject();
|
final JSONObject jsonObject = new JSONObject();
|
||||||
|
|
||||||
JSONArray jsonArray = new JSONArray(jsonObject, JSONConfig.of());
|
JSONArray jsonArray = JSONUtil.parseArray(jsonObject, JSONConfig.of());
|
||||||
assertEquals(new JSONArray(), jsonArray);
|
assertEquals(new JSONArray(), jsonArray);
|
||||||
|
|
||||||
jsonObject.set("key1", "value1");
|
jsonObject.set("key1", "value1");
|
||||||
jsonArray = new JSONArray(jsonObject, JSONConfig.of());
|
jsonArray = JSONUtil.parseArray(jsonObject, JSONConfig.of());
|
||||||
assertEquals(1, jsonArray.size());
|
assertEquals(1, jsonArray.size());
|
||||||
assertEquals("[{\"key1\":\"value1\"}]", jsonArray.toString());
|
assertEquals("[{\"key1\":\"value1\"}]", jsonArray.toString());
|
||||||
}
|
}
|
||||||
@ -70,9 +70,9 @@ public class JSONArrayTest {
|
|||||||
final JSONArray array = JSONUtil.ofArray();
|
final JSONArray array = JSONUtil.ofArray();
|
||||||
// 方法2
|
// 方法2
|
||||||
// JSONArray array = new JSONArray();
|
// JSONArray array = new JSONArray();
|
||||||
array.add("value1");
|
array.set("value1");
|
||||||
array.add("value2");
|
array.set("value2");
|
||||||
array.add("value3");
|
array.set("value3");
|
||||||
|
|
||||||
assertEquals(array.get(0), "value1");
|
assertEquals(array.get(0), "value1");
|
||||||
}
|
}
|
||||||
@ -238,12 +238,12 @@ public class JSONArrayTest {
|
|||||||
@Test
|
@Test
|
||||||
public void putToIndexTest() {
|
public void putToIndexTest() {
|
||||||
JSONArray jsonArray = new JSONArray();
|
JSONArray jsonArray = new JSONArray();
|
||||||
jsonArray.set(3, "test");
|
jsonArray.setValue(3, "test");
|
||||||
// 默认忽略null值,因此空位无值,只有一个值
|
// 默认忽略null值,因此空位无值,只有一个值
|
||||||
assertEquals(1, jsonArray.size());
|
assertEquals(1, jsonArray.size());
|
||||||
|
|
||||||
jsonArray = new JSONArray(JSONConfig.of().setIgnoreNullValue(false));
|
jsonArray = new JSONArray(JSONConfig.of().setIgnoreNullValue(false));
|
||||||
jsonArray.set(2, "test");
|
jsonArray.setValue(2, "test");
|
||||||
// 第三个位置插入值,0~2都是null
|
// 第三个位置插入值,0~2都是null
|
||||||
assertEquals(3, jsonArray.size());
|
assertEquals(3, jsonArray.size());
|
||||||
}
|
}
|
||||||
@ -252,7 +252,7 @@ public class JSONArrayTest {
|
|||||||
@Test
|
@Test
|
||||||
public void putTest2() {
|
public void putTest2() {
|
||||||
final JSONArray jsonArray = new JSONArray();
|
final JSONArray jsonArray = new JSONArray();
|
||||||
jsonArray.put(0, 1);
|
jsonArray.setValue(0, 1);
|
||||||
assertEquals(1, jsonArray.size());
|
assertEquals(1, jsonArray.size());
|
||||||
assertEquals(1, jsonArray.get(0));
|
assertEquals(1, jsonArray.get(0));
|
||||||
}
|
}
|
||||||
@ -307,7 +307,7 @@ public class JSONArrayTest {
|
|||||||
public void parseFilterTest() {
|
public void parseFilterTest() {
|
||||||
final String jsonArr = "[{\"id\":111,\"name\":\"test1\"},{\"id\":112,\"name\":\"test2\"}]";
|
final String jsonArr = "[{\"id\":111,\"name\":\"test1\"},{\"id\":112,\"name\":\"test2\"}]";
|
||||||
//noinspection MismatchedQueryAndUpdateOfCollection
|
//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());
|
assertEquals(1, array.size());
|
||||||
assertTrue(array.getJSONObject(0).containsKey("id"));
|
assertTrue(array.getJSONObject(0).containsKey("id"));
|
||||||
}
|
}
|
||||||
@ -316,7 +316,7 @@ public class JSONArrayTest {
|
|||||||
public void parseFilterEditTest() {
|
public void parseFilterEditTest() {
|
||||||
final String jsonArr = "[{\"id\":111,\"name\":\"test1\"},{\"id\":112,\"name\":\"test2\"}]";
|
final String jsonArr = "[{\"id\":111,\"name\":\"test1\"},{\"id\":112,\"name\":\"test2\"}]";
|
||||||
//noinspection MismatchedQueryAndUpdateOfCollection
|
//noinspection MismatchedQueryAndUpdateOfCollection
|
||||||
final JSONArray array = new JSONArray(jsonArr, null, (mutable) -> {
|
final JSONArray array = JSONUtil.parseArray(jsonArr, null, (mutable) -> {
|
||||||
if(mutable.getKey() instanceof Integer){
|
if(mutable.getKey() instanceof Integer){
|
||||||
final JSONObject o = (JSONObject) mutable.getValue();
|
final JSONObject o = (JSONObject) mutable.getValue();
|
||||||
if ("111".equals(o.getStr("id"))) {
|
if ("111".equals(o.getStr("id"))) {
|
||||||
|
@ -42,7 +42,7 @@ public class JSONNullTest {
|
|||||||
" \"device_model\": null,\n" +
|
" \"device_model\": null,\n" +
|
||||||
" \"device_status_date\": null,\n" +
|
" \"device_status_date\": null,\n" +
|
||||||
" \"imsi\": 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_model"));
|
||||||
Assertions.assertFalse(bodyjson.containsKey("device_status_date"));
|
Assertions.assertFalse(bodyjson.containsKey("device_status_date"));
|
||||||
Assertions.assertFalse(bodyjson.containsKey("imsi"));
|
Assertions.assertFalse(bodyjson.containsKey("imsi"));
|
||||||
|
@ -313,7 +313,7 @@ public class JSONObjectTest {
|
|||||||
userA.setDate(new Date());
|
userA.setDate(new Date());
|
||||||
userA.setSqs(ListUtil.of(new Seq(null), new Seq("seq2")));
|
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.containsKey("a"));
|
||||||
Assertions.assertTrue(json.getJSONArray("sqs").getJSONObject(0).containsKey("seq"));
|
Assertions.assertTrue(json.getJSONArray("sqs").getJSONObject(0).containsKey("seq"));
|
||||||
@ -328,7 +328,8 @@ public class JSONObjectTest {
|
|||||||
bean.setStrValue("strTest");
|
bean.setStrValue("strTest");
|
||||||
bean.setTestEnum(TestEnum.TYPE_B);
|
bean.setTestEnum(TestEnum.TYPE_B);
|
||||||
|
|
||||||
final JSONObject json = JSONUtil.parseObj(bean, false);
|
final JSONObject json = JSONUtil.parseObj(bean,
|
||||||
|
JSONConfig.of().setIgnoreNullValue(false));
|
||||||
// 枚举转换检查,更新:枚举原样保存,在writer时调用toString。
|
// 枚举转换检查,更新:枚举原样保存,在writer时调用toString。
|
||||||
Assertions.assertEquals(TestEnum.TYPE_B, json.getObj("testEnum"));
|
Assertions.assertEquals(TestEnum.TYPE_B, json.getObj("testEnum"));
|
||||||
|
|
||||||
@ -396,7 +397,8 @@ public class JSONObjectTest {
|
|||||||
final JSONObject userAJson = JSONUtil.parseObj(userA);
|
final JSONObject userAJson = JSONUtil.parseObj(userA);
|
||||||
Assertions.assertFalse(userAJson.containsKey("a"));
|
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("a"));
|
||||||
Assertions.assertTrue(userAJsonWithNullValue.containsKey("sqs"));
|
Assertions.assertTrue(userAJsonWithNullValue.containsKey("sqs"));
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ package org.dromara.hutool.json;
|
|||||||
|
|
||||||
import org.dromara.hutool.core.io.IoUtil;
|
import org.dromara.hutool.core.io.IoUtil;
|
||||||
import org.dromara.hutool.core.io.resource.ResourceUtil;
|
import org.dromara.hutool.core.io.resource.ResourceUtil;
|
||||||
|
import org.dromara.hutool.core.lang.Console;
|
||||||
import org.dromara.hutool.json.reader.JSONTokener;
|
import org.dromara.hutool.json.reader.JSONTokener;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
@ -29,6 +30,7 @@ public class JSONTokenerTest {
|
|||||||
void parseTest() {
|
void parseTest() {
|
||||||
final JSONObject jsonObject = JSONUtil.parseObj(ResourceUtil.getUtf8Reader("issue1200.json"));
|
final JSONObject jsonObject = JSONUtil.parseObj(ResourceUtil.getUtf8Reader("issue1200.json"));
|
||||||
assertNotNull(jsonObject);
|
assertNotNull(jsonObject);
|
||||||
|
Console.log(jsonObject.toStringPretty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -37,6 +37,7 @@ public class TransientTest {
|
|||||||
//noinspection MismatchedQueryAndUpdateOfCollection
|
//noinspection MismatchedQueryAndUpdateOfCollection
|
||||||
final JSONObject jsonObject = JSONUtil.parseObj(detailBill,
|
final JSONObject jsonObject = JSONUtil.parseObj(detailBill,
|
||||||
JSONConfig.of().setTransientSupport(false));
|
JSONConfig.of().setTransientSupport(false));
|
||||||
|
|
||||||
Assertions.assertEquals("{\"id\":\"3243\",\"bizNo\":\"bizNo\"}", jsonObject.toString());
|
Assertions.assertEquals("{\"id\":\"3243\",\"bizNo\":\"bizNo\"}", jsonObject.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,12 +16,15 @@
|
|||||||
|
|
||||||
package org.dromara.hutool.json.engine;
|
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.DateTime;
|
||||||
import org.dromara.hutool.core.date.DateUtil;
|
import org.dromara.hutool.core.date.DateUtil;
|
||||||
import org.dromara.hutool.core.date.TimeUtil;
|
import org.dromara.hutool.core.date.TimeUtil;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class GsonTest {
|
public class GsonTest {
|
||||||
/**
|
/**
|
||||||
* Gson默认缩进两个空格,使用\n换行符
|
* Gson默认缩进两个空格,使用\n换行符
|
||||||
@ -54,4 +57,11 @@ public class GsonTest {
|
|||||||
Assertions.assertEquals("{\"date\":\"2024-01-01 00:00:00\"}", engine.toJsonString(bean));
|
Assertions.assertEquals("{\"date\":\"2024-01-01 00:00:00\"}", engine.toJsonString(bean));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void arrayToStringTest() {
|
||||||
|
final ArrayList<Integer> integers = ListUtil.of(1, 2, 3);
|
||||||
|
final JSONEngine engine = JSONEngineFactory.createEngine("gson");
|
||||||
|
final String jsonString = engine.toJsonString(integers);
|
||||||
|
Assertions.assertEquals("[1,2,3]", jsonString);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,13 +16,16 @@
|
|||||||
|
|
||||||
package org.dromara.hutool.json.jwt;
|
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.DatePattern;
|
||||||
import org.dromara.hutool.core.date.DateUtil;
|
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.core.util.ByteUtil;
|
||||||
import org.dromara.hutool.json.jwt.signers.AlgorithmUtil;
|
import org.dromara.hutool.json.jwt.signers.AlgorithmUtil;
|
||||||
import org.dromara.hutool.json.jwt.signers.JWTSigner;
|
import org.dromara.hutool.json.jwt.signers.JWTSigner;
|
||||||
import org.dromara.hutool.json.jwt.signers.JWTSignerUtil;
|
import org.dromara.hutool.json.jwt.signers.JWTSignerUtil;
|
||||||
import lombok.Data;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
@ -132,12 +135,12 @@ public class JWTTest {
|
|||||||
final List<Integer> list = Arrays.asList(1, 2, 3);
|
final List<Integer> list = Arrays.asList(1, 2, 3);
|
||||||
final Integer num = 18;
|
final Integer num = 18;
|
||||||
final String username = "takaki";
|
final String username = "takaki";
|
||||||
final HashMap<String, String> map = new HashMap<>();
|
final Map<String, String> map = new HashMap<>();
|
||||||
map.put("test1", "1");
|
map.put("test1", "1");
|
||||||
map.put("test2", "2");
|
map.put("test2", "2");
|
||||||
|
|
||||||
final Map<String, Object> payload = new HashMap<String, Object>() {
|
final Map<String, Object> payload = new HashMap<String, Object>() {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
{
|
{
|
||||||
put("username", username);
|
put("username", username);
|
||||||
put("bean", bean);
|
put("bean", bean);
|
||||||
@ -155,17 +158,20 @@ public class JWTTest {
|
|||||||
final Date dateRes = jwt.getPayload("date", Date.class);
|
final Date dateRes = jwt.getPayload("date", Date.class);
|
||||||
final List<?> listRes = jwt.getPayload("list", List.class);
|
final List<?> listRes = jwt.getPayload("list", List.class);
|
||||||
final Integer numRes = jwt.getPayload("number", Integer.class);
|
final Integer numRes = jwt.getPayload("number", Integer.class);
|
||||||
final HashMap<?, ?> mapRes = jwt.getPayload("map", HashMap.class);
|
final Map<String, String> mapRes = jwt.getPayload("map", new TypeReference<Map<String, String>>(){});
|
||||||
|
|
||||||
Assertions.assertEquals(bean, beanRes);
|
Assertions.assertEquals(bean, beanRes);
|
||||||
Assertions.assertEquals(numRes, num);
|
Assertions.assertEquals(numRes, num);
|
||||||
Assertions.assertEquals(username, strRes);
|
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 formattedDate = DateUtil.format(date, "yyyy-MM-dd HH:mm:ss");
|
||||||
final String formattedRes = DateUtil.format(dateRes, "yyyy-MM-dd HH:mm:ss");
|
final String formattedRes = DateUtil.format(dateRes, "yyyy-MM-dd HH:mm:ss");
|
||||||
Assertions.assertEquals(formattedDate, formattedRes);
|
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()
|
@Test()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user