This commit is contained in:
Looly 2023-03-10 13:07:05 +08:00
parent 869b12000d
commit 35feac4eae
13 changed files with 123 additions and 336 deletions

View File

@ -4,12 +4,12 @@ import cn.hutool.core.compress.ZipUtil;
import cn.hutool.core.io.file.FileReader; import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.io.file.*; import cn.hutool.core.io.file.*;
import cn.hutool.core.io.file.FileWriter; import cn.hutool.core.io.file.FileWriter;
import cn.hutool.core.io.file.FileReader.ReaderHandler;
import cn.hutool.core.io.resource.ResourceUtil; import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.io.stream.BOMInputStream; import cn.hutool.core.io.stream.BOMInputStream;
import cn.hutool.core.io.unit.DataSizeUtil; import cn.hutool.core.io.unit.DataSizeUtil;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.func.SerConsumer; import cn.hutool.core.lang.func.SerConsumer;
import cn.hutool.core.lang.func.SerFunction;
import cn.hutool.core.net.url.URLUtil; import cn.hutool.core.net.url.URLUtil;
import cn.hutool.core.reflect.ClassUtil; import cn.hutool.core.reflect.ClassUtil;
import cn.hutool.core.regex.ReUtil; import cn.hutool.core.regex.ReUtil;
@ -1976,10 +1976,9 @@ public class FileUtil extends PathUtil {
* @param path 文件的绝对路径 * @param path 文件的绝对路径
* @return 从文件中load出的数据 * @return 从文件中load出的数据
* @throws IORuntimeException IO异常 * @throws IORuntimeException IO异常
* @since 3.1.1
*/ */
public static <T> T loadUtf8(final String path, final ReaderHandler<T> readerHandler) throws IORuntimeException { public static <T> T readUtf8(final String path, final SerFunction<BufferedReader, T> readerHandler) throws IORuntimeException {
return load(path, CharsetUtil.UTF_8, readerHandler); return read(path, CharsetUtil.UTF_8, readerHandler);
} }
/** /**
@ -1993,23 +1992,8 @@ public class FileUtil extends PathUtil {
* @throws IORuntimeException IO异常 * @throws IORuntimeException IO异常
* @since 3.1.1 * @since 3.1.1
*/ */
public static <T> T load(final String path, final String charset, final ReaderHandler<T> readerHandler) throws IORuntimeException { public static <T> T read(final String path, final Charset charset, final SerFunction<BufferedReader, T> readerHandler) throws IORuntimeException {
return FileReader.of(file(path), CharsetUtil.charset(charset)).read(readerHandler); return read(file(path), charset, readerHandler);
}
/**
* 按照给定的readerHandler读取文件中的数据
*
* @param <T> 集合类型
* @param readerHandler Reader处理类
* @param path 文件的绝对路径
* @param charset 字符集
* @return 从文件中load出的数据
* @throws IORuntimeException IO异常
* @since 3.1.1
*/
public static <T> T load(final String path, final Charset charset, final ReaderHandler<T> readerHandler) throws IORuntimeException {
return FileReader.of(file(path), charset).read(readerHandler);
} }
/** /**
@ -2022,8 +2006,8 @@ public class FileUtil extends PathUtil {
* @throws IORuntimeException IO异常 * @throws IORuntimeException IO异常
* @since 3.1.1 * @since 3.1.1
*/ */
public static <T> T loadUtf8(final File file, final ReaderHandler<T> readerHandler) throws IORuntimeException { public static <T> T readUtf8(final File file, final SerFunction<BufferedReader, T> readerHandler) throws IORuntimeException {
return load(file, CharsetUtil.UTF_8, readerHandler); return read(file, CharsetUtil.UTF_8, readerHandler);
} }
/** /**
@ -2037,7 +2021,7 @@ public class FileUtil extends PathUtil {
* @throws IORuntimeException IO异常 * @throws IORuntimeException IO异常
* @since 3.1.1 * @since 3.1.1
*/ */
public static <T> T load(final File file, final Charset charset, final ReaderHandler<T> readerHandler) throws IORuntimeException { public static <T> T read(final File file, final Charset charset, final SerFunction<BufferedReader, T> readerHandler) throws IORuntimeException {
return FileReader.of(file, charset).read(readerHandler); return FileReader.of(file, charset).read(readerHandler);
} }

View File

@ -1,9 +1,11 @@
package cn.hutool.core.io.file; package cn.hutool.core.io.file;
import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IORuntimeException; import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil; import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.func.SerConsumer; import cn.hutool.core.lang.func.SerConsumer;
import cn.hutool.core.lang.func.SerFunction;
import cn.hutool.core.text.StrUtil; import cn.hutool.core.text.StrUtil;
import cn.hutool.core.util.CharsetUtil; import cn.hutool.core.util.CharsetUtil;
@ -17,6 +19,7 @@ import java.nio.charset.Charset;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.function.Function;
/** /**
* 文件读取器 * 文件读取器
@ -207,14 +210,20 @@ public class FileReader extends FileWrapper {
* @return 从文件中read出的数据 * @return 从文件中read出的数据
* @throws IORuntimeException IO异常 * @throws IORuntimeException IO异常
*/ */
public <T> T read(final ReaderHandler<T> readerHandler) throws IORuntimeException { public <T> T read(final SerFunction<BufferedReader, T> readerHandler) throws IORuntimeException {
BufferedReader reader = null; BufferedReader reader = null;
T result; T result;
try { try {
reader = FileUtil.getReader(this.file, charset); reader = FileUtil.getReader(this.file, charset);
result = readerHandler.handle(reader); result = readerHandler.applying(reader);
} catch (final IOException e) { } catch (final Exception e) {
throw new IORuntimeException(e); if(e instanceof IOException){
throw new IORuntimeException(e);
} else if(e instanceof RuntimeException){
throw (RuntimeException)e;
} else{
throw new UtilException(e);
}
} finally { } finally {
IoUtil.close(reader); IoUtil.close(reader);
} }
@ -277,19 +286,6 @@ public class FileReader extends FileWrapper {
} }
} }
// -------------------------------------------------------------------------- Interface start
/**
* Reader处理接口
*
* @author Luxiaolei
*
* @param <T> Reader处理返回结果类型
*/
public interface ReaderHandler<T> {
T handle(BufferedReader reader) throws IOException;
}
// -------------------------------------------------------------------------- Interface end
/** /**
* 检查文件 * 检查文件
* *

View File

@ -1,12 +1,14 @@
package cn.hutool.core.util; package cn.hutool.core.util;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil; import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.exceptions.UtilException; import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IORuntimeException; import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil; import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Console;
import cn.hutool.core.map.BiMap; import cn.hutool.core.map.BiMap;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
import cn.hutool.core.text.StrUtil; import cn.hutool.core.text.StrUtil;
@ -181,7 +183,8 @@ public class XmlUtil {
* @return XML文档对象 * @return XML文档对象
* @since 3.0.9 * @since 3.0.9
*/ */
public static Document readXML(final String pathOrContent) { public static Document readXML(String pathOrContent) {
pathOrContent = StrUtil.trim(pathOrContent);
if (StrUtil.startWith(pathOrContent, '<')) { if (StrUtil.startWith(pathOrContent, '<')) {
return parseXml(pathOrContent); return parseXml(pathOrContent);
} }
@ -985,11 +988,7 @@ public class XmlUtil {
public static <T> T xmlToBean(final Node node, final Class<T> bean) { public static <T> T xmlToBean(final Node node, final Class<T> bean) {
final Map<String, Object> map = xmlToMap(node); final Map<String, Object> map = xmlToMap(node);
if (null != map && map.size() == 1) { if (null != map && map.size() == 1) {
final String simpleName = bean.getSimpleName(); return BeanUtil.toBean(CollUtil.get(map.values(), 0), bean);
if (map.containsKey(simpleName)) {
// 只有key和bean的名称匹配时才做单一对象转换
return BeanUtil.toBean(map.get(simpleName), bean);
}
} }
return BeanUtil.toBean(map, bean); return BeanUtil.toBean(map, bean);
} }

View File

@ -7,6 +7,7 @@ import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.junit.runners.Parameterized; import org.junit.runners.Parameterized;
@ -71,6 +72,7 @@ public class LambdaFactoryTest {
* @author nasodaengineer * @author nasodaengineer
*/ */
@RunWith(Parameterized.class) @RunWith(Parameterized.class)
@Ignore
public static class PerformanceTest { public static class PerformanceTest {
@Parameterized.Parameter @Parameterized.Parameter
@ -140,6 +142,7 @@ public class LambdaFactoryTest {
@SuppressWarnings({"rawtypes", "unchecked", "Convert2MethodRef"}) @SuppressWarnings({"rawtypes", "unchecked", "Convert2MethodRef"})
@Test @Test
@SneakyThrows @SneakyThrows
@Ignore
public void lambdaGetPerformanceTest() { public void lambdaGetPerformanceTest() {
final Something something = new Something(); final Something something = new Something();
something.setId(1L); something.setId(1L);
@ -216,6 +219,7 @@ public class LambdaFactoryTest {
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
@Test @Test
@SneakyThrows @SneakyThrows
@Ignore
public void lambdaSetPerformanceTest() { public void lambdaSetPerformanceTest() {
final Something something = new Something(); final Something something = new Something();
something.setId(1L); something.setId(1L);

View File

@ -348,4 +348,23 @@ public class XmlUtilTest {
Console.log(XmlUtil.format(doc)); Console.log(XmlUtil.format(doc));
} }
@Test
public void xmlStrToBeanTest(){
final String xml = "<user><name>张三</name><age>20</age><email>zhangsan@example.com</email></user>";
final Document document = XmlUtil.readXML(xml);
final UserInfo userInfo = XmlUtil.xmlToBean(document, UserInfo.class);
Assert.assertEquals("张三", userInfo.getName());
Assert.assertEquals("20", userInfo.getAge());
Assert.assertEquals("zhangsan@example.com", userInfo.getEmail());
}
@Data
static class UserInfo {
private String id;
private String name;
private String age;
private String email;
}
} }

View File

@ -1,81 +0,0 @@
package cn.hutool.json;
import cn.hutool.core.lang.mutable.MutableEntry;
import cn.hutool.core.math.NumberUtil;
import java.io.IOException;
import java.io.Writer;
import java.util.function.Predicate;
/**
* JSON数字表示
*
* @author looly
* @since 6.0.0
*/
public class JSONNumber extends Number implements JSON {
private static final long serialVersionUID = 1L;
private final Number value;
/**
* 配置项
*/
private final JSONConfig config;
/**
* 构造
*
* @param value
* @param config JSON配置
*/
public JSONNumber(final Number value, final JSONConfig config) {
this.value = value;
this.config = config;
}
@Override
public JSONConfig getConfig() {
return this.config;
}
@Override
public int size() {
return 1;
}
@Override
public Writer write(final Writer writer, final int indentFactor, final int indent,
final Predicate<MutableEntry<Object, Object>> predicate) throws JSONException {
try {
writer.write(toString());
} catch (final IOException e) {
throw new RuntimeException(e);
}
return writer;
}
@Override
public int intValue() {
return this.value.intValue();
}
@Override
public long longValue() {
return this.value.longValue();
}
@Override
public float floatValue() {
return this.value.floatValue();
}
@Override
public double doubleValue() {
return this.value.doubleValue();
}
@Override
public String toString() {
return NumberUtil.toStr(this.value);
}
}

View File

@ -1,76 +0,0 @@
package cn.hutool.json;
import cn.hutool.core.lang.mutable.MutableEntry;
import java.io.IOException;
import java.io.Writer;
import java.util.function.Predicate;
/**
* JSON字符串表示一个字符串
*
* @author looly
* @since 6.0.0
*/
public class JSONString implements JSON, CharSequence {
private static final long serialVersionUID = 1L;
private final char[] value;
/**
* 配置项
*/
private final JSONConfig config;
/**
* 构造
*
* @param value char数组
* @param config 配置项
*/
public JSONString(final char[] value, final JSONConfig config) {
this.value = value;
this.config = config;
}
@Override
public JSONConfig getConfig() {
return this.config;
}
@Override
public int size() {
return length();
}
@Override
public Writer write(final Writer writer, final int indentFactor, final int indent,
final Predicate<MutableEntry<Object, Object>> predicate) throws JSONException {
try {
writer.write(this.value);
} catch (final IOException e) {
throw new RuntimeException(e);
}
return writer;
}
@Override
public int length() {
return this.value.length;
}
@Override
public char charAt(final int index) {
return this.value[index];
}
@Override
public CharSequence subSequence(final int start, final int end) {
return ((start == 0) && (end == this.value.length)) ? this
: new String(this.value, start, end);
}
@Override
public String toString() {
return String.valueOf(this.value);
}
}

View File

@ -2,6 +2,7 @@ package cn.hutool.json;
import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IORuntimeException; import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.reflect.TypeReference; import cn.hutool.core.reflect.TypeReference;
import cn.hutool.core.text.StrUtil; import cn.hutool.core.text.StrUtil;
import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.ObjUtil;
@ -27,7 +28,6 @@ import java.util.List;
public class JSONUtil { public class JSONUtil {
// -------------------------------------------------------------------- Pause start // -------------------------------------------------------------------- Pause start
/** /**
* 创建JSONObject * 创建JSONObject
* *
@ -139,8 +139,8 @@ public class JSONUtil {
* @param obj 对象 * @param obj 对象
* @return JSON * @return JSON
*/ */
public static JSON parse(final Object obj) { public static Object parse(final Object obj) {
return JSONConverter.INSTANCE.toJSON(obj); return parse(obj, null);
} }
/** /**
@ -154,10 +154,12 @@ public class JSONUtil {
* *
* @param obj 对象 * @param obj 对象
* @param config JSON配置{@code null}使用默认配置 * @param config JSON配置{@code null}使用默认配置
* @return JSON * @return JSONJSONObject or JSONArray
* @since 5.3.1
*/ */
public static JSON parse(final Object obj, final JSONConfig config) { public static Object parse(final Object obj, final JSONConfig config) {
if(null == config){
return JSONConverter.INSTANCE.toJSON(obj);
}
return JSONConverter.of(config).toJSON(obj); return JSONConverter.of(config).toJSON(obj);
} }
@ -173,6 +175,7 @@ public class JSONUtil {
// -------------------------------------------------------------------- Parse end // -------------------------------------------------------------------- Parse end
// -------------------------------------------------------------------- Read start // -------------------------------------------------------------------- Read start
/** /**
* 读取JSON * 读取JSON
* *
@ -182,11 +185,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 {
try (final Reader reader = FileUtil.getReader(file, charset)) { return (JSON) FileUtil.read(file, charset, JSONUtil::parse);
return parse(reader);
} catch (final IOException e) {
throw new IORuntimeException(e);
}
} }
/** /**
@ -198,11 +197,7 @@ public class JSONUtil {
* @throws IORuntimeException IO异常 * @throws IORuntimeException IO异常
*/ */
public static JSONObject readJSONObject(final File file, final Charset charset) throws IORuntimeException { public static JSONObject readJSONObject(final File file, final Charset charset) throws IORuntimeException {
try (final Reader reader = FileUtil.getReader(file, charset)) { return FileUtil.read(file, charset, JSONUtil::parseObj);
return parseObj(reader);
} catch (final IOException e) {
throw new IORuntimeException(e);
}
} }
/** /**
@ -214,67 +209,23 @@ public class JSONUtil {
* @throws IORuntimeException IO异常 * @throws IORuntimeException IO异常
*/ */
public static JSONArray readJSONArray(final File file, final Charset charset) throws IORuntimeException { public static JSONArray readJSONArray(final File file, final Charset charset) throws IORuntimeException {
try (final Reader reader = FileUtil.getReader(file, charset)) { return FileUtil.read(file, charset, JSONUtil::parseArray);
return parseArray(reader);
} catch (final IOException e) {
throw new IORuntimeException(e);
}
} }
// -------------------------------------------------------------------- Read end // -------------------------------------------------------------------- Read end
// -------------------------------------------------------------------- toString start // -------------------------------------------------------------------- toString start
/** /**
* 为JSON字符串 * 格式化后的JSON字符串
* *
* @param json JSON * @param obj Bean对象
* @param indentFactor 每一级别的缩进
* @return JSON字符串 * @return JSON字符串
*/ */
public static String toJsonStr(final JSON json, final int indentFactor) { public static String toJsonPrettyStr(Object obj) {
if (null == json) { obj = parse(obj);
return null; if (obj instanceof JSON) {
return ((JSON) obj).toStringPretty();
} }
return json.toJSONString(indentFactor); return StrUtil.toStringOrNull(obj);
}
/**
* 转为JSON字符串
*
* @param json JSON
* @return JSON字符串
*/
public static String toJsonStr(final JSON json) {
if (null == json) {
return null;
}
return json.toJSONString(0);
}
/**
* 转为JSON字符串并写出到write
*
* @param json JSON
* @param writer Writer
* @since 5.3.3
*/
public static void toJsonStr(final JSON json, final Writer writer) {
if (null != json) {
json.write(writer);
}
}
/**
* 转为JSON字符串
*
* @param json JSON
* @return JSON字符串
*/
public static String toJsonPrettyStr(final JSON json) {
if (null == json) {
return null;
}
return json.toStringPretty();
} }
/** /**
@ -299,7 +250,7 @@ public class JSONUtil {
public static String toJsonStr(final Object obj, final JSONConfig jsonConfig) { public static String toJsonStr(final Object obj, final JSONConfig jsonConfig) {
// 自定义规则优先级高于全局规则 // 自定义规则优先级高于全局规则
final JSONValueWriter valueWriter = InternalJSONUtil.getValueWriter(obj); final JSONValueWriter valueWriter = InternalJSONUtil.getValueWriter(obj);
if(null != valueWriter){ if (null != valueWriter) {
final StringWriter stringWriter = new StringWriter(); final StringWriter stringWriter = new StringWriter();
final JSONWriter jsonWriter = JSONWriter.of(stringWriter, 0, 0, null); final JSONWriter jsonWriter = JSONWriter.of(stringWriter, 0, 0, null);
// 用户对象自定义实现了JSONValueWriter接口理解为需要自定义输出 // 用户对象自定义实现了JSONValueWriter接口理解为需要自定义输出
@ -307,17 +258,10 @@ public class JSONUtil {
return stringWriter.toString(); return stringWriter.toString();
} }
if (null == obj) { if(null == obj){
return null; return null;
} }
if (obj instanceof CharSequence) { return parse(obj, jsonConfig).toString();
return StrUtil.str((CharSequence) obj);
}
if (obj instanceof Number) {
return obj.toString();
}
return toJsonStr(parse(obj, jsonConfig));
} }
/** /**
@ -327,20 +271,20 @@ public class JSONUtil {
* @param writer Writer * @param writer Writer
* @since 5.3.3 * @since 5.3.3
*/ */
public static void toJsonStr(final Object obj, final Writer writer) { public static void toJsonStr(Object obj, final Writer writer) {
if (null != obj) { if (null != obj) {
toJsonStr(parse(obj), writer); obj = parse(obj);
} if (obj instanceof JSON) {
} ((JSON) obj).write(writer);
}
/** // 普通值
* 转换为格式化后的JSON字符串 try {
* writer.write(obj.toString());
* @param obj Bean对象 } catch (final IOException e) {
* @return JSON字符串 throw new IORuntimeException(e);
*/ }
public static String toJsonPrettyStr(final Object obj) { }
return toJsonPrettyStr(parse(obj));
} }
/** /**
@ -393,7 +337,7 @@ public class JSONUtil {
* @since 5.8.0 * @since 5.8.0
*/ */
public static <T> T toBean(final String jsonString, final JSONConfig config, final Class<T> beanClass) { public static <T> T toBean(final String jsonString, final JSONConfig config, final Class<T> beanClass) {
return toBean(parse(jsonString, config), beanClass); return toBean(jsonString, config, (Type) beanClass);
} }
/** /**
@ -405,23 +349,12 @@ public class JSONUtil {
* @param config JSON配置 * @param config JSON配置
* @param type Bean类型 * @param type Bean类型
* @return 实体类对象 * @return 实体类对象
* @throws JSONException 提供的JSON字符串不支持转Bean或字符串错误
*/ */
public static <T> T toBean(final String jsonString, final JSONConfig config, final Type type) { public static <T> T toBean(final String jsonString, final JSONConfig config, final Type type) throws JSONException {
return toBean(parse(jsonString, config), type); return toBean(parse(jsonString, config), type);
} }
/**
* 转为实体类对象转换异常将被抛出
*
* @param <T> Bean类型
* @param json JSONObject
* @param beanClass 实体类对象
* @return 实体类对象
*/
public static <T> T toBean(final JSONObject json, final Class<T> beanClass) {
return null == json ? null : json.toBean(beanClass);
}
/** /**
* 转为实体类对象 * 转为实体类对象
* *
@ -431,24 +364,27 @@ public class JSONUtil {
* @return 实体类对象 * @return 实体类对象
* @since 4.6.2 * @since 4.6.2
*/ */
public static <T> T toBean(final JSON json, final TypeReference<T> typeReference) { public static <T> T toBean(final Object json, final TypeReference<T> typeReference) {
return toBean(json, typeReference.getType()); return toBean(json, typeReference.getType());
} }
/** /**
* 转为实体类对象 * 转为实体类对象
* *
* @param <T> Bean类型 * @param <T> Bean类型
* @param json JSONObject * @param json JSONObject
* @param beanType 实体类对象类型 * @param type 实体类对象类型
* @return 实体类对象 * @return 实体类对象
* @since 4.3.2 * @since 4.3.2
*/ */
public static <T> T toBean(final JSON json, final Type beanType) { public static <T> T toBean(final Object json, final Type type) {
if (null == json) { if (null == json) {
return null; return null;
} }
return json.toBean(beanType); if (json instanceof JSON) {
return ((JSON) json).toBean(type);
}
throw new JSONException("Unsupported json string to bean : {}", json);
} }
// -------------------------------------------------------------------- toBean end // -------------------------------------------------------------------- toBean end
@ -562,13 +498,13 @@ public class JSONUtil {
* @param json JSONObject或JSONArray * @param json JSONObject或JSONArray
* @return 是否为空 * @return 是否为空
*/ */
public static boolean isEmpty(final JSON json){ public static boolean isEmpty(final JSON json) {
if(null == json){ if (null == json) {
return true; return true;
} }
if(json instanceof JSONObject){ if (json instanceof JSONObject) {
return ((JSONObject) json).isEmpty(); return ((JSONObject) json).isEmpty();
} else if(json instanceof JSONArray){ } else if (json instanceof JSONArray) {
return ((JSONArray) json).isEmpty(); return ((JSONArray) json).isEmpty();
} }
return false; return false;

View File

@ -111,32 +111,34 @@ public class JSONConverter implements Converter {
/** /**
* 实现Object对象转换为{@link JSON}支持的对象 * 实现Object对象转换为{@link JSON}支持的对象
* <ul> * <ul>
* <li>String: 转换为相应的对象</li> * <li>String: 转换为相应的对象</li>
* <li>ArrayIterableIterator转换为JSONArray</li> * <li>ArrayIterableIterator转换为JSONArray</li>
* <li>Bean对象转为JSONObject</li> * <li>Bean对象转为JSONObject</li>
* <li>Number返回原对象</li>
* </ul> * </ul>
* *
* @param obj 被转换的对象 * @param obj 被转换的对象
* @return 转换后的对象 * @return 转换后的对象
* @throws JSONException 转换异常 * @throws JSONException 转换异常
*/ */
public JSON toJSON(final Object obj) throws JSONException { public Object toJSON(final Object obj) throws JSONException {
final JSON json; final JSON json;
if (obj instanceof JSON) { if (obj instanceof JSON || obj instanceof Number) {
json = (JSON) obj; return obj;
} else if (obj instanceof CharSequence) { } else if (obj instanceof CharSequence) {
final String jsonStr = StrUtil.trim((CharSequence) obj); final String jsonStr = StrUtil.trim((CharSequence) obj);
switch (jsonStr.charAt(0)){ switch (jsonStr.charAt(0)){
case '"': case '"':
case '\'': case '\'':
return new JSONString(jsonStr.toCharArray(), config); // JSON字符串值
return jsonStr;
case '[': case '[':
return new JSONArray(jsonStr, config); return new JSONArray(jsonStr, config);
case '{': case '{':
return new JSONObject(jsonStr, config); return new JSONObject(jsonStr, config);
default: default:
if(NumberUtil.isNumber(jsonStr)){ if(NumberUtil.isNumber(jsonStr)){
return new JSONNumber(NumberUtil.toBigDecimal(jsonStr), config); return NumberUtil.toBigDecimal(jsonStr);
} }
throw new JSONException("Unsupported String to JSON: {}", jsonStr); throw new JSONException("Unsupported String to JSON: {}", jsonStr);
} }

View File

@ -3,32 +3,34 @@ package cn.hutool.json;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import java.math.BigDecimal;
public class IssueI6LBZATest { public class IssueI6LBZATest {
@Test @Test
public void parseJSONStringTest() { public void parseJSONStringTest() {
final String a = "\"a\""; final String a = "\"a\"";
final JSON parse = JSONUtil.parse(a); final Object parse = JSONUtil.parse(a);
Assert.assertEquals(JSONString.class, parse.getClass()); Assert.assertEquals(String.class, parse.getClass());
} }
@Test @Test
public void parseJSONStringTest2() { public void parseJSONStringTest2() {
final String a = "'a'"; final String a = "'a'";
final JSON parse = JSONUtil.parse(a); final Object parse = JSONUtil.parse(a);
Assert.assertEquals(JSONString.class, parse.getClass()); Assert.assertEquals(String.class, parse.getClass());
} }
@Test(expected = JSONException.class) @Test(expected = JSONException.class)
public void parseJSONErrorTest() { public void parseJSONErrorTest() {
final String a = "a"; final String a = "a";
final JSON parse = JSONUtil.parse(a); final Object parse = JSONUtil.parse(a);
Assert.assertEquals(JSONString.class, parse.getClass()); Assert.assertEquals(String.class, parse.getClass());
} }
@Test @Test
public void parseJSONNumberTest() { public void parseJSONNumberTest() {
final String a = "123"; final String a = "123";
final JSON parse = JSONUtil.parse(a); final Object parse = JSONUtil.parse(a);
Assert.assertEquals(JSONNumber.class, parse.getClass()); Assert.assertEquals(BigDecimal.class, parse.getClass());
} }
} }

View File

@ -42,8 +42,7 @@ public class JSONArrayTest {
@Test @Test
public void addNullTest() { public void addNullTest() {
final List<String> aaa = ListUtil.view("aaa", null); final List<String> aaa = ListUtil.view("aaa", null);
final String jsonStr = JSONUtil.toJsonStr(JSONUtil.parse(aaa, final String jsonStr = JSONUtil.toJsonStr(JSONUtil.parse(aaa, JSONConfig.of().setIgnoreNullValue(false)));
JSONConfig.of().setIgnoreNullValue(false)));
Assert.assertEquals("[\"aaa\",null]", jsonStr); Assert.assertEquals("[\"aaa\",null]", jsonStr);
} }

View File

@ -23,7 +23,7 @@ public class JSONPathTest {
@Test @Test
public void getByPathTest2(){ public void getByPathTest2(){
final String str = "{'accountId':111}"; final String str = "{'accountId':111}";
final JSON json = JSONUtil.parse(str); final JSON json = (JSON) JSONUtil.parse(str);
final Long accountId = JSONUtil.getByPath(json, "$.accountId", 0L); final Long accountId = JSONUtil.getByPath(json, "$.accountId", 0L);
Assert.assertEquals(111L, accountId.longValue()); Assert.assertEquals(111L, accountId.longValue());
} }

View File

@ -2,6 +2,7 @@ package cn.hutool.json;
import cn.hutool.core.collection.ListUtil; import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Console;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
import cn.hutool.core.math.NumberUtil; import cn.hutool.core.math.NumberUtil;
import cn.hutool.json.serialize.JSONStringer; import cn.hutool.json.serialize.JSONStringer;
@ -235,9 +236,11 @@ public class JSONUtilTest {
Assert.assertEquals("<key1>v1</key1><key2>a</key2><key2>b</key2><key2>c</key2>", xmlStr); Assert.assertEquals("<key1>v1</key1><key2>a</key2><key2>b</key2><key2>c</key2>", xmlStr);
} }
@Test @Test(expected = JSONException.class)
public void toJsonStrOfStringTest(){ public void toJsonStrOfStringTest(){
final String a = "a"; final String a = "a";
// 普通字符串不能解析为JSON字符串必须由双引号或者单引号包裹
final String s = JSONUtil.toJsonStr(a); final String s = JSONUtil.toJsonStr(a);
Assert.assertEquals(a, s); Assert.assertEquals(a, s);
} }