mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
add class
This commit is contained in:
parent
741babe2c8
commit
65552f4f54
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
# 5.4.5 (2020-10-16)
|
# 5.4.5 (2020-10-17)
|
||||||
|
|
||||||
### 新特性
|
### 新特性
|
||||||
* 【core 】 ConsoleTable代码优化(pr#190@Gitee)
|
* 【core 】 ConsoleTable代码优化(pr#190@Gitee)
|
||||||
@ -20,6 +20,8 @@
|
|||||||
* 【core 】 优化针对list的split方法(pr#194@Gitee)
|
* 【core 】 优化针对list的split方法(pr#194@Gitee)
|
||||||
* 【poi 】 ExcelWriter增加setRowStyle方法
|
* 【poi 】 ExcelWriter增加setRowStyle方法
|
||||||
* 【core 】 Assert增加函数接口(pr#1166@Github)
|
* 【core 】 Assert增加函数接口(pr#1166@Github)
|
||||||
|
* 【core 】 新增AtomicIntegerArray、AtomicLongArray转换
|
||||||
|
* 【extra 】 PinyinUtil新增Bopomofo4j支持
|
||||||
|
|
||||||
### Bug修复
|
### Bug修复
|
||||||
* 【core 】 解决农历判断节日未判断大小月导致的问题(issue#I1XHSF@Gitee)
|
* 【core 】 解决农历判断节日未判断大小月导致的问题(issue#I1XHSF@Gitee)
|
||||||
|
@ -3,6 +3,8 @@ package cn.hutool.core.convert;
|
|||||||
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
import cn.hutool.core.convert.impl.ArrayConverter;
|
import cn.hutool.core.convert.impl.ArrayConverter;
|
||||||
import cn.hutool.core.convert.impl.AtomicBooleanConverter;
|
import cn.hutool.core.convert.impl.AtomicBooleanConverter;
|
||||||
|
import cn.hutool.core.convert.impl.AtomicIntegerArrayConverter;
|
||||||
|
import cn.hutool.core.convert.impl.AtomicLongArrayConverter;
|
||||||
import cn.hutool.core.convert.impl.AtomicReferenceConverter;
|
import cn.hutool.core.convert.impl.AtomicReferenceConverter;
|
||||||
import cn.hutool.core.convert.impl.BeanConverter;
|
import cn.hutool.core.convert.impl.BeanConverter;
|
||||||
import cn.hutool.core.convert.impl.BooleanConverter;
|
import cn.hutool.core.convert.impl.BooleanConverter;
|
||||||
@ -69,7 +71,9 @@ import java.util.UUID;
|
|||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.concurrent.atomic.AtomicIntegerArray;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
import java.util.concurrent.atomic.AtomicLongArray;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -423,6 +427,10 @@ public class ConverterRegistry implements Serializable {
|
|||||||
defaultConverterMap.put(SoftReference.class, new ReferenceConverter(SoftReference.class));// since 3.0.8
|
defaultConverterMap.put(SoftReference.class, new ReferenceConverter(SoftReference.class));// since 3.0.8
|
||||||
defaultConverterMap.put(AtomicReference.class, new AtomicReferenceConverter());// since 3.0.8
|
defaultConverterMap.put(AtomicReference.class, new AtomicReferenceConverter());// since 3.0.8
|
||||||
|
|
||||||
|
//AtomicXXXArray,since 5.4.5
|
||||||
|
defaultConverterMap.put(AtomicIntegerArray.class, new AtomicIntegerArrayConverter());
|
||||||
|
defaultConverterMap.put(AtomicLongArray.class, new AtomicLongArrayConverter());
|
||||||
|
|
||||||
// 其它类型
|
// 其它类型
|
||||||
defaultConverterMap.put(Class.class, new ClassConverter());
|
defaultConverterMap.put(Class.class, new ClassConverter());
|
||||||
defaultConverterMap.put(TimeZone.class, new TimeZoneConverter());
|
defaultConverterMap.put(TimeZone.class, new TimeZoneConverter());
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
package cn.hutool.core.convert.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.convert.AbstractConverter;
|
||||||
|
import cn.hutool.core.convert.Convert;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicIntegerArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link AtomicIntegerArray}转换器
|
||||||
|
*
|
||||||
|
* @author Looly
|
||||||
|
* @since 5.4.5
|
||||||
|
*/
|
||||||
|
public class AtomicIntegerArrayConverter extends AbstractConverter<AtomicIntegerArray> {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected AtomicIntegerArray convertInternal(Object value) {
|
||||||
|
return new AtomicIntegerArray(Convert.convert(int[].class, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package cn.hutool.core.convert.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.convert.AbstractConverter;
|
||||||
|
import cn.hutool.core.convert.Convert;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicLongArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link AtomicLongArray}转换器
|
||||||
|
*
|
||||||
|
* @author Looly
|
||||||
|
* @since 5.4.5
|
||||||
|
*/
|
||||||
|
public class AtomicLongArrayConverter extends AbstractConverter<AtomicLongArray> {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected AtomicLongArray convertInternal(Object value) {
|
||||||
|
return new AtomicLongArray(Convert.convert(long[].class, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -13,6 +13,8 @@ import java.util.Calendar;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
import java.util.concurrent.atomic.DoubleAdder;
|
||||||
|
import java.util.concurrent.atomic.LongAdder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数字转换器<br>
|
* 数字转换器<br>
|
||||||
@ -64,7 +66,6 @@ public class NumberConverter extends AbstractConverter<Number> {
|
|||||||
}
|
}
|
||||||
final String valueStr = convertToStr(value);
|
final String valueStr = convertToStr(value);
|
||||||
return StrUtil.isBlank(valueStr) ? null : Byte.valueOf(valueStr);
|
return StrUtil.isBlank(valueStr) ? null : Byte.valueOf(valueStr);
|
||||||
|
|
||||||
} else if (Short.class == targetType) {
|
} else if (Short.class == targetType) {
|
||||||
if (value instanceof Number) {
|
if (value instanceof Number) {
|
||||||
return ((Number) value).shortValue();
|
return ((Number) value).shortValue();
|
||||||
@ -73,7 +74,6 @@ public class NumberConverter extends AbstractConverter<Number> {
|
|||||||
}
|
}
|
||||||
final String valueStr = convertToStr(value);
|
final String valueStr = convertToStr(value);
|
||||||
return StrUtil.isBlank(valueStr) ? null : Short.valueOf(valueStr);
|
return StrUtil.isBlank(valueStr) ? null : Short.valueOf(valueStr);
|
||||||
|
|
||||||
} else if (Integer.class == targetType) {
|
} else if (Integer.class == targetType) {
|
||||||
if (value instanceof Number) {
|
if (value instanceof Number) {
|
||||||
return ((Number) value).intValue();
|
return ((Number) value).intValue();
|
||||||
@ -88,7 +88,6 @@ public class NumberConverter extends AbstractConverter<Number> {
|
|||||||
}
|
}
|
||||||
final String valueStr = convertToStr(value);
|
final String valueStr = convertToStr(value);
|
||||||
return StrUtil.isBlank(valueStr) ? null : NumberUtil.parseInt(valueStr);
|
return StrUtil.isBlank(valueStr) ? null : NumberUtil.parseInt(valueStr);
|
||||||
|
|
||||||
} else if (AtomicInteger.class == targetType) {
|
} else if (AtomicInteger.class == targetType) {
|
||||||
final Number number = convertInternal(value, Integer.class);
|
final Number number = convertInternal(value, Integer.class);
|
||||||
if (null != number) {
|
if (null != number) {
|
||||||
@ -96,7 +95,6 @@ public class NumberConverter extends AbstractConverter<Number> {
|
|||||||
intValue.set(number.intValue());
|
intValue.set(number.intValue());
|
||||||
return intValue;
|
return intValue;
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
} else if (Long.class == targetType) {
|
} else if (Long.class == targetType) {
|
||||||
if (value instanceof Number) {
|
if (value instanceof Number) {
|
||||||
return ((Number) value).longValue();
|
return ((Number) value).longValue();
|
||||||
@ -111,7 +109,6 @@ public class NumberConverter extends AbstractConverter<Number> {
|
|||||||
}
|
}
|
||||||
final String valueStr = convertToStr(value);
|
final String valueStr = convertToStr(value);
|
||||||
return StrUtil.isBlank(valueStr) ? null : NumberUtil.parseLong(valueStr);
|
return StrUtil.isBlank(valueStr) ? null : NumberUtil.parseLong(valueStr);
|
||||||
|
|
||||||
} else if (AtomicLong.class == targetType) {
|
} else if (AtomicLong.class == targetType) {
|
||||||
final Number number = convertInternal(value, Long.class);
|
final Number number = convertInternal(value, Long.class);
|
||||||
if (null != number) {
|
if (null != number) {
|
||||||
@ -119,7 +116,14 @@ public class NumberConverter extends AbstractConverter<Number> {
|
|||||||
longValue.set(number.longValue());
|
longValue.set(number.longValue());
|
||||||
return longValue;
|
return longValue;
|
||||||
}
|
}
|
||||||
return null;
|
}else if (LongAdder.class == targetType) {
|
||||||
|
//jdk8 新增
|
||||||
|
final Number number = convertInternal(value, Long.class);
|
||||||
|
if (null != number) {
|
||||||
|
final LongAdder longValue = new LongAdder();
|
||||||
|
longValue.add(number.longValue());
|
||||||
|
return longValue;
|
||||||
|
}
|
||||||
} else if (Float.class == targetType) {
|
} else if (Float.class == targetType) {
|
||||||
if (value instanceof Number) {
|
if (value instanceof Number) {
|
||||||
return ((Number) value).floatValue();
|
return ((Number) value).floatValue();
|
||||||
@ -137,13 +141,18 @@ public class NumberConverter extends AbstractConverter<Number> {
|
|||||||
}
|
}
|
||||||
final String valueStr = convertToStr(value);
|
final String valueStr = convertToStr(value);
|
||||||
return StrUtil.isBlank(valueStr) ? null : Double.valueOf(valueStr);
|
return StrUtil.isBlank(valueStr) ? null : Double.valueOf(valueStr);
|
||||||
|
}else if (DoubleAdder.class == targetType) {
|
||||||
|
//jdk8 新增
|
||||||
|
final Number number = convertInternal(value, Long.class);
|
||||||
|
if (null != number) {
|
||||||
|
final DoubleAdder doubleAdder = new DoubleAdder();
|
||||||
|
doubleAdder.add(number.doubleValue());
|
||||||
|
return doubleAdder;
|
||||||
|
}
|
||||||
} else if (BigDecimal.class == targetType) {
|
} else if (BigDecimal.class == targetType) {
|
||||||
return toBigDecimal(value);
|
return toBigDecimal(value);
|
||||||
|
|
||||||
} else if (BigInteger.class == targetType) {
|
} else if (BigInteger.class == targetType) {
|
||||||
return toBigInteger(value);
|
return toBigInteger(value);
|
||||||
|
|
||||||
} else if (Number.class == targetType) {
|
} else if (Number.class == targetType) {
|
||||||
if (value instanceof Number) {
|
if (value instanceof Number) {
|
||||||
return (Number) value;
|
return (Number) value;
|
||||||
@ -166,22 +175,14 @@ public class NumberConverter extends AbstractConverter<Number> {
|
|||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
private BigDecimal toBigDecimal(Object value) {
|
private BigDecimal toBigDecimal(Object value) {
|
||||||
if (value instanceof Long) {
|
if (value instanceof Number) {
|
||||||
return new BigDecimal((Long) value);
|
return NumberUtil.toBigDecimal((Number) value);
|
||||||
} else if (value instanceof Integer) {
|
|
||||||
return new BigDecimal((Integer) value);
|
|
||||||
} else if (value instanceof BigInteger) {
|
|
||||||
return new BigDecimal((BigInteger) value);
|
|
||||||
} else if (value instanceof Boolean) {
|
} else if (value instanceof Boolean) {
|
||||||
return new BigDecimal((boolean) value ? 1 : 0);
|
return new BigDecimal((boolean) value ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//对于Double类型,先要转换为String,避免精度问题
|
//对于Double类型,先要转换为String,避免精度问题
|
||||||
final String valueStr = convertToStr(value);
|
return NumberUtil.toBigDecimal(convertToStr(value));
|
||||||
if (StrUtil.isBlank(valueStr)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return new BigDecimal(valueStr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -198,11 +199,8 @@ public class NumberConverter extends AbstractConverter<Number> {
|
|||||||
} else if (value instanceof Boolean) {
|
} else if (value instanceof Boolean) {
|
||||||
return BigInteger.valueOf((boolean) value ? 1 : 0);
|
return BigInteger.valueOf((boolean) value ? 1 : 0);
|
||||||
}
|
}
|
||||||
final String valueStr = convertToStr(value);
|
|
||||||
if (StrUtil.isBlank(valueStr)) {
|
return NumberUtil.toBigInteger(convertToStr(value));
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return new BigInteger(valueStr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,18 +1,77 @@
|
|||||||
package cn.hutool.core.convert.impl;
|
package cn.hutool.core.convert.impl;
|
||||||
|
|
||||||
import cn.hutool.core.convert.AbstractConverter;
|
import cn.hutool.core.convert.AbstractConverter;
|
||||||
|
import cn.hutool.core.convert.ConvertException;
|
||||||
|
import cn.hutool.core.io.IoUtil;
|
||||||
|
import cn.hutool.core.util.CharsetUtil;
|
||||||
|
import cn.hutool.core.util.XmlUtil;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.sql.Blob;
|
||||||
|
import java.sql.Clob;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 字符串转换器
|
* 字符串转换器,提供各种对象转换为字符串的逻辑封装
|
||||||
* @author Looly
|
|
||||||
*
|
*
|
||||||
|
* @author Looly
|
||||||
*/
|
*/
|
||||||
public class StringConverter extends AbstractConverter<String>{
|
public class StringConverter extends AbstractConverter<String> {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String convertInternal(Object value) {
|
protected String convertInternal(Object value) {
|
||||||
|
if (value instanceof TimeZone) {
|
||||||
|
return ((TimeZone) value).getID();
|
||||||
|
} else if (value instanceof org.w3c.dom.Node) {
|
||||||
|
return XmlUtil.toStr((org.w3c.dom.Node) value);
|
||||||
|
} else if (value instanceof Clob) {
|
||||||
|
return clobToStr((Clob) value);
|
||||||
|
} else if (value instanceof Blob) {
|
||||||
|
return blobToStr((Blob) value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 其它情况
|
||||||
return convertToStr(value);
|
return convertToStr(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clob字段值转字符串
|
||||||
|
*
|
||||||
|
* @param clob {@link Clob}
|
||||||
|
* @return 字符串
|
||||||
|
* @since 5.4.5
|
||||||
|
*/
|
||||||
|
private static String clobToStr(Clob clob) {
|
||||||
|
Reader reader = null;
|
||||||
|
try {
|
||||||
|
reader = clob.getCharacterStream();
|
||||||
|
return IoUtil.read(reader);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new ConvertException(e);
|
||||||
|
} finally {
|
||||||
|
IoUtil.close(reader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Blob字段值转字符串
|
||||||
|
*
|
||||||
|
* @param blob {@link Blob}
|
||||||
|
* @return 字符串
|
||||||
|
* @since 5.4.5
|
||||||
|
*/
|
||||||
|
private static String blobToStr(Blob blob) {
|
||||||
|
InputStream in = null;
|
||||||
|
try {
|
||||||
|
in = blob.getBinaryStream();
|
||||||
|
return IoUtil.read(in, CharsetUtil.CHARSET_UTF_8);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new ConvertException(e);
|
||||||
|
} finally {
|
||||||
|
IoUtil.close(in);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2005,6 +2005,17 @@ public class NumberUtil {
|
|||||||
if (null == number) {
|
if (null == number) {
|
||||||
return BigDecimal.ZERO;
|
return BigDecimal.ZERO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(number instanceof BigDecimal){
|
||||||
|
return (BigDecimal) number;
|
||||||
|
} else if (number instanceof Long) {
|
||||||
|
return new BigDecimal((Long) number);
|
||||||
|
} else if (number instanceof Integer) {
|
||||||
|
return new BigDecimal((Integer) number);
|
||||||
|
} else if (number instanceof BigInteger) {
|
||||||
|
return new BigDecimal((BigInteger) number);
|
||||||
|
}
|
||||||
|
|
||||||
return toBigDecimal(number.toString());
|
return toBigDecimal(number.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2019,6 +2030,38 @@ public class NumberUtil {
|
|||||||
return (null == number) ? BigDecimal.ZERO : new BigDecimal(number);
|
return (null == number) ? BigDecimal.ZERO : new BigDecimal(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数字转{@link BigInteger}
|
||||||
|
*
|
||||||
|
* @param number 数字
|
||||||
|
* @return {@link BigInteger}
|
||||||
|
* @since 5.4.5
|
||||||
|
*/
|
||||||
|
public static BigInteger toBigInteger(Number number) {
|
||||||
|
if (null == number) {
|
||||||
|
return BigInteger.ZERO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(number instanceof BigInteger){
|
||||||
|
return (BigInteger) number;
|
||||||
|
} else if (number instanceof Long) {
|
||||||
|
return BigInteger.valueOf((Long) number);
|
||||||
|
}
|
||||||
|
|
||||||
|
return toBigInteger(number.longValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数字转{@link BigInteger}
|
||||||
|
*
|
||||||
|
* @param number 数字
|
||||||
|
* @return {@link BigInteger}
|
||||||
|
* @since 5.4.5
|
||||||
|
*/
|
||||||
|
public static BigInteger toBigInteger(String number) {
|
||||||
|
return (null == number) ? BigInteger.ZERO : new BigInteger(number);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否空白符<br>
|
* 是否空白符<br>
|
||||||
* 空白符包括空格、制表符、全角空格和不间断空格<br>
|
* 空白符包括空格、制表符、全角空格和不间断空格<br>
|
||||||
|
@ -345,6 +345,19 @@ public class XmlUtil {
|
|||||||
|
|
||||||
// -------------------------------------------------------------------------------------- Write
|
// -------------------------------------------------------------------------------------- Write
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将XML文档转换为String<br>
|
||||||
|
* 字符编码使用XML文档中的编码,获取不到则使用UTF-8<br>
|
||||||
|
* 默认非格式化输出,若想格式化请使用{@link #format(Document)}
|
||||||
|
*
|
||||||
|
* @param doc XML文档
|
||||||
|
* @return XML字符串
|
||||||
|
* @since 5.4.5
|
||||||
|
*/
|
||||||
|
public static String toStr(Node doc) {
|
||||||
|
return toStr(doc, false);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将XML文档转换为String<br>
|
* 将XML文档转换为String<br>
|
||||||
* 字符编码使用XML文档中的编码,获取不到则使用UTF-8<br>
|
* 字符编码使用XML文档中的编码,获取不到则使用UTF-8<br>
|
||||||
@ -354,7 +367,20 @@ public class XmlUtil {
|
|||||||
* @return XML字符串
|
* @return XML字符串
|
||||||
*/
|
*/
|
||||||
public static String toStr(Document doc) {
|
public static String toStr(Document doc) {
|
||||||
return toStr(doc, false);
|
return toStr((Node)doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将XML文档转换为String<br>
|
||||||
|
* 字符编码使用XML文档中的编码,获取不到则使用UTF-8
|
||||||
|
*
|
||||||
|
* @param doc XML文档
|
||||||
|
* @param isPretty 是否格式化输出
|
||||||
|
* @return XML字符串
|
||||||
|
* @since 5.4.5
|
||||||
|
*/
|
||||||
|
public static String toStr(Node doc, boolean isPretty) {
|
||||||
|
return toStr(doc, CharsetUtil.UTF_8, isPretty);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -367,7 +393,21 @@ public class XmlUtil {
|
|||||||
* @since 3.0.9
|
* @since 3.0.9
|
||||||
*/
|
*/
|
||||||
public static String toStr(Document doc, boolean isPretty) {
|
public static String toStr(Document doc, boolean isPretty) {
|
||||||
return toStr(doc, CharsetUtil.UTF_8, isPretty);
|
return toStr((Node)doc, isPretty);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将XML文档转换为String<br>
|
||||||
|
* 字符编码使用XML文档中的编码,获取不到则使用UTF-8
|
||||||
|
*
|
||||||
|
* @param doc XML文档
|
||||||
|
* @param charset 编码
|
||||||
|
* @param isPretty 是否格式化输出
|
||||||
|
* @return XML字符串
|
||||||
|
* @since 5.4.5
|
||||||
|
*/
|
||||||
|
public static String toStr(Node doc, String charset, boolean isPretty) {
|
||||||
|
return toStr(doc, charset, isPretty, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -381,7 +421,7 @@ public class XmlUtil {
|
|||||||
* @since 3.0.9
|
* @since 3.0.9
|
||||||
*/
|
*/
|
||||||
public static String toStr(Document doc, String charset, boolean isPretty) {
|
public static String toStr(Document doc, String charset, boolean isPretty) {
|
||||||
return toStr(doc, charset, isPretty, false);
|
return toStr((Node)doc, charset, isPretty);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -395,7 +435,7 @@ public class XmlUtil {
|
|||||||
* @return XML字符串
|
* @return XML字符串
|
||||||
* @since 5.1.2
|
* @since 5.1.2
|
||||||
*/
|
*/
|
||||||
public static String toStr(Document doc, String charset, boolean isPretty, boolean omitXmlDeclaration) {
|
public static String toStr(Node doc, String charset, boolean isPretty, boolean omitXmlDeclaration) {
|
||||||
final StringWriter writer = StrUtil.getWriter();
|
final StringWriter writer = StrUtil.getWriter();
|
||||||
try {
|
try {
|
||||||
write(doc, writer, charset, isPretty ? INDENT_DEFAULT : 0, omitXmlDeclaration);
|
write(doc, writer, charset, isPretty ? INDENT_DEFAULT : 0, omitXmlDeclaration);
|
||||||
|
@ -9,6 +9,8 @@ import java.io.Serializable;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.atomic.AtomicIntegerArray;
|
||||||
|
import java.util.concurrent.atomic.AtomicLongArray;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 类型转换工具单元测试
|
* 类型转换工具单元测试
|
||||||
@ -222,6 +224,20 @@ public class ConvertTest {
|
|||||||
Assert.assertEquals("5.1.1", product.getVersion());
|
Assert.assertEquals("5.1.1", product.getVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void toAtomicIntegerArrayTest(){
|
||||||
|
String str = "1,2";
|
||||||
|
final AtomicIntegerArray atomicIntegerArray = Convert.convert(AtomicIntegerArray.class, str);
|
||||||
|
Assert.assertEquals("[1, 2]", atomicIntegerArray.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void toAtomicLongArrayTest(){
|
||||||
|
String str = "1,2";
|
||||||
|
final AtomicLongArray atomicLongArray = Convert.convert(AtomicLongArray.class, str);
|
||||||
|
Assert.assertEquals("[1, 2]", atomicLongArray.toString());
|
||||||
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public static class Product implements Serializable {
|
public static class Product implements Serializable {
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
package cn.hutool.core.convert;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
public class StringConvertTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void timezoneToStrTest(){
|
||||||
|
final String s = Convert.toStr(TimeZone.getTimeZone("Asia/Shanghai"));
|
||||||
|
Assert.assertEquals("Asia/Shanghai", s);
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
@ -233,6 +233,12 @@
|
|||||||
<version>1.1.8</version>
|
<version>1.1.8</version>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.rnkrsoft.bopomofo4j</groupId>
|
||||||
|
<artifactId>bopomofo4j</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cglib</groupId>
|
<groupId>cglib</groupId>
|
||||||
<artifactId>cglib</artifactId>
|
<artifactId>cglib</artifactId>
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
package cn.hutool.extra.pinyin.engine.bopomofo4j;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.extra.pinyin.PinyinEngine;
|
||||||
|
import com.rnkrsoft.bopomofo4j.Bopomofo4j;
|
||||||
|
import com.rnkrsoft.bopomofo4j.ToneType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 封装了Bopomofo4j的引擎。
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Bopomofo4j封装,项目:https://gitee.com/rnkrsoft/Bopomofo4j。
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* 引入:
|
||||||
|
* <pre>
|
||||||
|
* <dependency>
|
||||||
|
* <groupId>com.rnkrsoft.bopomofo4j</groupId>
|
||||||
|
* <artifactId>bopomofo4j</artifactId>
|
||||||
|
* <version>1.0.0</version>
|
||||||
|
* </dependency>
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author looly
|
||||||
|
* @since 5.4.5
|
||||||
|
*/
|
||||||
|
public class Bopomofo4jEngine implements PinyinEngine {
|
||||||
|
|
||||||
|
public Bopomofo4jEngine(){
|
||||||
|
Bopomofo4j.local();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPinyin(char c) {
|
||||||
|
return Bopomofo4j.pinyin(String.valueOf(c), ToneType.WITHOUT_TONE, false, false, StrUtil.EMPTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPinyin(String str, String separator) {
|
||||||
|
return Bopomofo4j.pinyin(str, ToneType.WITHOUT_TONE, false, false, separator);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
* 封装了Bopomofo4j的引擎。
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Bopomofo4j封装,项目:https://gitee.com/rnkrsoft/Bopomofo4j。
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* 引入:
|
||||||
|
* <pre>
|
||||||
|
* <dependency>
|
||||||
|
* <groupId>com.rnkrsoft.bopomofo4j</groupId>
|
||||||
|
* <artifactId>bopomofo4j</artifactId>
|
||||||
|
* <version>1.0.0</version>
|
||||||
|
* </dependency>
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author looly
|
||||||
|
*/
|
||||||
|
package cn.hutool.extra.pinyin.engine.bopomofo4j;
|
@ -1,3 +1,4 @@
|
|||||||
cn.hutool.extra.pinyin.engine.tinypinyin.TinyPinyinEngine
|
cn.hutool.extra.pinyin.engine.tinypinyin.TinyPinyinEngine
|
||||||
cn.hutool.extra.pinyin.engine.jpinyin.JPinyinEngine
|
cn.hutool.extra.pinyin.engine.jpinyin.JPinyinEngine
|
||||||
cn.hutool.extra.pinyin.engine.pinyin4j.Pinyin4jEngine
|
cn.hutool.extra.pinyin.engine.pinyin4j.Pinyin4jEngine
|
||||||
|
cn.hutool.extra.pinyin.engine.bopomofo4j.Bopomofo4jEngine
|
@ -1,5 +1,6 @@
|
|||||||
package cn.hutool.extra.pinyin;
|
package cn.hutool.extra.pinyin;
|
||||||
|
|
||||||
|
import cn.hutool.extra.pinyin.engine.bopomofo4j.Bopomofo4jEngine;
|
||||||
import cn.hutool.extra.pinyin.engine.pinyin4j.Pinyin4jEngine;
|
import cn.hutool.extra.pinyin.engine.pinyin4j.Pinyin4jEngine;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@ -19,6 +20,13 @@ public class PinyinUtilTest {
|
|||||||
Assert.assertEquals("ni hao h", pinyin);
|
Assert.assertEquals("ni hao h", pinyin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getPinyinByBopomofo4jTest() {
|
||||||
|
final Bopomofo4jEngine engine = new Bopomofo4jEngine();
|
||||||
|
final String pinyin = engine.getPinyin("你好h", " ");
|
||||||
|
Assert.assertEquals("ni haoh", pinyin);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getPinyinUpperCaseTest(){
|
public void getPinyinUpperCaseTest(){
|
||||||
final String pinyin = PinyinUtil.getPinyin("你好怡", " ");
|
final String pinyin = PinyinUtil.getPinyin("你好怡", " ");
|
||||||
@ -37,4 +45,11 @@ public class PinyinUtilTest {
|
|||||||
final String result = engine.getFirstLetter("林海", "");
|
final String result = engine.getFirstLetter("林海", "");
|
||||||
Assert.assertEquals("lh", result);
|
Assert.assertEquals("lh", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getFirstLetterByBopomofo4jTest(){
|
||||||
|
final Bopomofo4jEngine engine = new Bopomofo4jEngine();
|
||||||
|
final String result = engine.getFirstLetter("林海", "");
|
||||||
|
Assert.assertEquals("lh", result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package cn.hutool.json;
|
|||||||
|
|
||||||
import cn.hutool.core.convert.Convert;
|
import cn.hutool.core.convert.Convert;
|
||||||
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import cn.hutool.core.date.TemporalAccessorUtil;
|
||||||
import cn.hutool.core.util.CharUtil;
|
import cn.hutool.core.util.CharUtil;
|
||||||
import cn.hutool.core.util.NumberUtil;
|
import cn.hutool.core.util.NumberUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
@ -239,6 +240,9 @@ final class InternalJSONUtil {
|
|||||||
*/
|
*/
|
||||||
private static String formatDate(Object dateObj, String format) {
|
private static String formatDate(Object dateObj, String format) {
|
||||||
if (StrUtil.isNotBlank(format)) {
|
if (StrUtil.isNotBlank(format)) {
|
||||||
|
if(dateObj instanceof TemporalAccessor){
|
||||||
|
return TemporalAccessorUtil.format((TemporalAccessor) dateObj, format);
|
||||||
|
}
|
||||||
//用户定义了日期格式
|
//用户定义了日期格式
|
||||||
return JSONUtil.quote(DateUtil.format(Convert.toDate(dateObj), format));
|
return JSONUtil.quote(DateUtil.format(Convert.toDate(dateObj), format));
|
||||||
}
|
}
|
||||||
|
@ -351,6 +351,18 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
|
|||||||
@Override
|
@Override
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public JSONObject put(String key, Object value) throws JSONException {
|
public JSONObject put(String key, Object value) throws JSONException {
|
||||||
|
return set(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置键值对到JSONObject中,在忽略null模式下,如果值为<code>null</code>,将此键移除
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param value 值对象. 可以是以下类型: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or the JSONNull.NULL.
|
||||||
|
* @return this.
|
||||||
|
* @throws JSONException 值是无穷数字抛出此异常
|
||||||
|
*/
|
||||||
|
public JSONObject set(String key, Object value) throws JSONException {
|
||||||
if (null == key) {
|
if (null == key) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -366,19 +378,6 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置键值对到JSONObject中,在忽略null模式下,如果值为<code>null</code>,将此键移除
|
|
||||||
*
|
|
||||||
* @param key 键
|
|
||||||
* @param value 值对象. 可以是以下类型: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or the JSONNull.NULL.
|
|
||||||
* @return this.
|
|
||||||
* @throws JSONException 值是无穷数字抛出此异常
|
|
||||||
*/
|
|
||||||
public JSONObject set(String key, Object value) throws JSONException {
|
|
||||||
put(key, value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 一次性Put 键值对,如果key已经存在抛出异常,如果键值中有null值,忽略
|
* 一次性Put 键值对,如果key已经存在抛出异常,如果键值中有null值,忽略
|
||||||
*
|
*
|
||||||
@ -392,7 +391,7 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
|
|||||||
if (rawHashMap.containsKey(key)) {
|
if (rawHashMap.containsKey(key)) {
|
||||||
throw new JSONException("Duplicate key \"{}\"", key);
|
throw new JSONException("Duplicate key \"{}\"", key);
|
||||||
}
|
}
|
||||||
this.put(key, value);
|
this.set(key, value);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -407,7 +406,7 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
|
|||||||
*/
|
*/
|
||||||
public JSONObject putOpt(String key, Object value) throws JSONException {
|
public JSONObject putOpt(String key, Object value) throws JSONException {
|
||||||
if (key != null && value != null) {
|
if (key != null && value != null) {
|
||||||
this.put(key, value);
|
this.set(key, value);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -415,7 +414,7 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
|
|||||||
@Override
|
@Override
|
||||||
public void putAll(Map<? extends String, ?> m) {
|
public void putAll(Map<? extends String, ?> m) {
|
||||||
for (Entry<? extends String, ?> entry : m.entrySet()) {
|
for (Entry<? extends String, ?> entry : m.entrySet()) {
|
||||||
this.put(entry.getKey(), entry.getValue());
|
this.set(entry.getKey(), entry.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -432,7 +431,7 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
|
|||||||
InternalJSONUtil.testValidity(value);
|
InternalJSONUtil.testValidity(value);
|
||||||
Object object = this.getObj(key);
|
Object object = this.getObj(key);
|
||||||
if (object == null) {
|
if (object == null) {
|
||||||
this.put(key, value instanceof JSONArray ? new JSONArray(this.config).set(value) : value);
|
this.set(key, value instanceof JSONArray ? new JSONArray(this.config).set(value) : value);
|
||||||
} else if (object instanceof JSONArray) {
|
} else if (object instanceof JSONArray) {
|
||||||
((JSONArray) object).set(value);
|
((JSONArray) object).set(value);
|
||||||
} else {
|
} else {
|
||||||
@ -472,19 +471,19 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
|
|||||||
public JSONObject increment(String key) throws JSONException {
|
public JSONObject increment(String key) throws JSONException {
|
||||||
Object value = this.getObj(key);
|
Object value = this.getObj(key);
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
this.put(key, 1);
|
this.set(key, 1);
|
||||||
} else if (value instanceof BigInteger) {
|
} else if (value instanceof BigInteger) {
|
||||||
this.put(key, ((BigInteger) value).add(BigInteger.ONE));
|
this.set(key, ((BigInteger) value).add(BigInteger.ONE));
|
||||||
} else if (value instanceof BigDecimal) {
|
} else if (value instanceof BigDecimal) {
|
||||||
this.put(key, ((BigDecimal) value).add(BigDecimal.ONE));
|
this.set(key, ((BigDecimal) value).add(BigDecimal.ONE));
|
||||||
} else if (value instanceof Integer) {
|
} else if (value instanceof Integer) {
|
||||||
this.put(key, (Integer) value + 1);
|
this.set(key, (Integer) value + 1);
|
||||||
} else if (value instanceof Long) {
|
} else if (value instanceof Long) {
|
||||||
this.put(key, (Long) value + 1);
|
this.set(key, (Long) value + 1);
|
||||||
} else if (value instanceof Double) {
|
} else if (value instanceof Double) {
|
||||||
this.put(key, (Double) value + 1);
|
this.set(key, (Double) value + 1);
|
||||||
} else if (value instanceof Float) {
|
} else if (value instanceof Float) {
|
||||||
this.put(key, (Float) value + 1);
|
this.set(key, (Float) value + 1);
|
||||||
} else {
|
} else {
|
||||||
throw new JSONException("Unable to increment [" + JSONUtil.quote(key) + "].");
|
throw new JSONException("Unable to increment [" + JSONUtil.quote(key) + "].");
|
||||||
}
|
}
|
||||||
@ -652,8 +651,11 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
|
|||||||
} else if (source instanceof Map) {
|
} else if (source instanceof Map) {
|
||||||
// Map
|
// Map
|
||||||
for (final Entry<?, ?> e : ((Map<?, ?>) source).entrySet()) {
|
for (final Entry<?, ?> e : ((Map<?, ?>) source).entrySet()) {
|
||||||
this.put(Convert.toStr(e.getKey()), e.getValue());
|
this.set(Convert.toStr(e.getKey()), e.getValue());
|
||||||
}
|
}
|
||||||
|
}else if (source instanceof Map.Entry) {
|
||||||
|
final Map.Entry entry = (Map.Entry) source;
|
||||||
|
this.set(Convert.toStr(entry.getKey()), entry.getValue());
|
||||||
} else if (source instanceof CharSequence) {
|
} else if (source instanceof CharSequence) {
|
||||||
// 可能为JSON字符串
|
// 可能为JSON字符串
|
||||||
init((CharSequence) source);
|
init((CharSequence) source);
|
||||||
|
@ -9,6 +9,7 @@ import cn.hutool.core.date.DateUtil;
|
|||||||
import cn.hutool.core.io.FileUtil;
|
import cn.hutool.core.io.FileUtil;
|
||||||
import cn.hutool.core.io.resource.ResourceUtil;
|
import cn.hutool.core.io.resource.ResourceUtil;
|
||||||
import cn.hutool.core.lang.Console;
|
import cn.hutool.core.lang.Console;
|
||||||
|
import cn.hutool.core.map.MapUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.json.test.bean.JSONBean;
|
import cn.hutool.json.test.bean.JSONBean;
|
||||||
import cn.hutool.json.test.bean.ResultDto;
|
import cn.hutool.json.test.bean.ResultDto;
|
||||||
@ -27,9 +28,13 @@ import org.junit.Ignore;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.sql.Timestamp;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JSONObject单元测试
|
* JSONObject单元测试
|
||||||
@ -425,6 +430,14 @@ public class JSONObjectTest {
|
|||||||
Assert.assertEquals("{\"date\":[\"2020-06-05 11:16:11\"],\"bbb\":[\"222\"],\"aaa\":[\"123\"]}", json.toString());
|
Assert.assertEquals("{\"date\":[\"2020-06-05 11:16:11\"],\"bbb\":[\"222\"],\"aaa\":[\"123\"]}", json.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getTimestampTest(){
|
||||||
|
String timeStr = "1970-01-01 00:00:00";
|
||||||
|
final JSONObject jsonObject = JSONUtil.createObj().set("time", timeStr);
|
||||||
|
final Timestamp time = jsonObject.get("time", Timestamp.class);
|
||||||
|
Assert.assertEquals("1970-01-01 00:00:00.0", time.toString());
|
||||||
|
}
|
||||||
|
|
||||||
public enum TestEnum {
|
public enum TestEnum {
|
||||||
TYPE_A, TYPE_B
|
TYPE_A, TYPE_B
|
||||||
}
|
}
|
||||||
@ -497,4 +510,14 @@ public class JSONObjectTest {
|
|||||||
return this.fieldToIgnore;
|
return this.fieldToIgnore;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setEntryTest(){
|
||||||
|
final HashMap<String, String> of = MapUtil.of("test", "testValue");
|
||||||
|
final Set<Map.Entry<String, String>> entries = of.entrySet();
|
||||||
|
final Map.Entry<String, String> next = entries.iterator().next();
|
||||||
|
|
||||||
|
final JSONObject jsonObject = JSONUtil.parseObj(next);
|
||||||
|
Console.log(jsonObject);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user