From 4417e5cd003e71e5fabe6978721c1a82cd71691e Mon Sep 17 00:00:00 2001 From: Looly Date: Thu, 23 Jun 2022 11:41:55 +0800 Subject: [PATCH] fix code --- .../core/convert/RegisterConverter.java | 1 + .../test/java/cn/hutool/http/RestTest.java | 10 +- .../hutool/http/server/SimpleServerTest.java | 2 +- .../java/cn/hutool/json/InternalJSONUtil.java | 170 +++++++++++- .../src/main/java/cn/hutool/json/JSON.java | 4 +- .../main/java/cn/hutool/json/JSONArray.java | 4 +- .../main/java/cn/hutool/json/JSONGetter.java | 6 +- .../main/java/cn/hutool/json/JSONObject.java | 8 +- .../main/java/cn/hutool/json/JSONSupport.java | 4 +- .../main/java/cn/hutool/json/JSONUtil.java | 243 +++--------------- .../cn/hutool/json/convert/JSONConverter.java | 226 +++++----------- .../hutool/json/convert/JSONConverterOld.java | 194 ++++++++++++++ .../convert/JSONDeserializerConverter.java | 2 +- .../cn/hutool/json/convert/package-info.java | 7 + .../hutool/json/serialize/DateJSONString.java | 4 +- .../cn/hutool/json/serialize/JSONWriter.java | 12 +- .../cn/hutool/json/CustomSerializeTest.java | 2 +- .../java/cn/hutool/json/IssueI59LW4Test.java | 4 +- .../java/cn/hutool/json/JSONArrayTest.java | 36 +-- .../java/cn/hutool/json/JSONNullTest.java | 8 +- .../java/cn/hutool/json/JSONObjectTest.java | 44 ++-- .../java/cn/hutool/json/JSONUtilTest.java | 10 +- .../test/java/cn/hutool/json/xml/XMLTest.java | 4 +- 23 files changed, 547 insertions(+), 458 deletions(-) create mode 100644 hutool-json/src/main/java/cn/hutool/json/convert/JSONConverterOld.java create mode 100644 hutool-json/src/main/java/cn/hutool/json/convert/package-info.java diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/RegisterConverter.java b/hutool-core/src/main/java/cn/hutool/core/convert/RegisterConverter.java index 8d9112eb9..89926d124 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/RegisterConverter.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/RegisterConverter.java @@ -69,6 +69,7 @@ import java.util.concurrent.atomic.AtomicReference; * @since 6.0.0 */ public class RegisterConverter implements Converter, Serializable { + private static final long serialVersionUID = 1L; /** * 默认类型转换器 diff --git a/hutool-http/src/test/java/cn/hutool/http/RestTest.java b/hutool-http/src/test/java/cn/hutool/http/RestTest.java index 588a03372..8a5da21fe 100644 --- a/hutool-http/src/test/java/cn/hutool/http/RestTest.java +++ b/hutool-http/src/test/java/cn/hutool/http/RestTest.java @@ -17,7 +17,7 @@ public class RestTest { @Test public void contentTypeTest() { final HttpRequest request = HttpRequest.post("http://localhost:8090/rest/restTest/")// - .body(JSONUtil.createObj() + .body(JSONUtil.ofObj() .set("aaa", "aaaValue") .set("键2", "值2").toString()); Assert.assertEquals("application/json;charset=UTF-8", request.header("Content-Type")); @@ -27,7 +27,7 @@ public class RestTest { @Ignore public void postTest() { final HttpRequest request = HttpRequest.post("http://localhost:8090/rest/restTest/")// - .body(JSONUtil.createObj() + .body(JSONUtil.ofObj() .set("aaa", "aaaValue") .set("键2", "值2").toString()); Console.log(request.execute().body()); @@ -36,7 +36,7 @@ public class RestTest { @Test @Ignore public void postTest2() { - final String result = HttpUtil.post("http://localhost:8090/rest/restTest/", JSONUtil.createObj()// + final String result = HttpUtil.post("http://localhost:8090/rest/restTest/", JSONUtil.ofObj()// .set("aaa", "aaaValue") .set("键2", "值2").toString()); Console.log(result); @@ -47,7 +47,7 @@ public class RestTest { public void getWithBodyTest() { final HttpRequest request = HttpRequest.get("http://localhost:8888/restTest")// .header(Header.CONTENT_TYPE, "application/json") - .body(JSONUtil.createObj() + .body(JSONUtil.ofObj() .set("aaa", "aaaValue") .set("键2", "值2").toString()); Console.log(request.execute().body()); @@ -60,7 +60,7 @@ public class RestTest { // Charles代理 .setHttpProxy("localhost", 8888) .header("Access-Token","") - .body(JSONUtil.createObj() + .body(JSONUtil.ofObj() .set("advertiser_ids", new Long[] {1690657248243790L}) .set("fields", new String[] {"id", "name", "status"}).toString()); Console.log(request); diff --git a/hutool-http/src/test/java/cn/hutool/http/server/SimpleServerTest.java b/hutool-http/src/test/java/cn/hutool/http/server/SimpleServerTest.java index 9681e2ec2..ad9f60a3f 100644 --- a/hutool-http/src/test/java/cn/hutool/http/server/SimpleServerTest.java +++ b/hutool-http/src/test/java/cn/hutool/http/server/SimpleServerTest.java @@ -27,7 +27,7 @@ public class SimpleServerTest { ) // 返回JSON数据测试 .addAction("/restTest", (request, response) -> { - final String res = JSONUtil.createObj() + final String res = JSONUtil.ofObj() .set("id", 1) .set("method", request.getMethod()) .set("request", request.getBody()) diff --git a/hutool-json/src/main/java/cn/hutool/json/InternalJSONUtil.java b/hutool-json/src/main/java/cn/hutool/json/InternalJSONUtil.java index 74c508e7d..f0c448f90 100755 --- a/hutool-json/src/main/java/cn/hutool/json/InternalJSONUtil.java +++ b/hutool-json/src/main/java/cn/hutool/json/InternalJSONUtil.java @@ -1,7 +1,9 @@ package cn.hutool.json; import cn.hutool.core.bean.copier.CopyOptions; +import cn.hutool.core.codec.HexUtil; import cn.hutool.core.convert.Convert; +import cn.hutool.core.io.IORuntimeException; import cn.hutool.core.lang.mutable.MutableEntry; import cn.hutool.core.map.CaseInsensitiveLinkedMap; import cn.hutool.core.map.CaseInsensitiveTreeMap; @@ -11,9 +13,12 @@ import cn.hutool.core.text.StrUtil; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.CharUtil; import cn.hutool.core.util.ObjUtil; -import cn.hutool.json.convert.JSONConverter; +import cn.hutool.json.convert.JSONConverterOld; import cn.hutool.json.serialize.JSONString; +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; import java.math.BigDecimal; import java.sql.SQLException; import java.time.temporal.TemporalAccessor; @@ -144,7 +149,7 @@ public final class InternalJSONUtil { } else if (ArrayUtil.isArray(value)) { return new JSONArray(value).toString(); } else { - return JSONUtil.quote(value.toString()); + return quote(value.toString()); } } @@ -255,7 +260,88 @@ public final class InternalJSONUtil { .setTransientSupport(config.isTransientSupport()) // 使用JSON转换器 .setConverter((type, value) -> - JSONConverter.convertWithCheck(type, value, null, config.isIgnoreError())); + JSONConverterOld.convertWithCheck(type, value, null, config.isIgnoreError())); + } + + /** + * 对所有双引号做转义处理(使用双反斜杠做转义)
+ * 为了能在HTML中较好的显示,会将</转义为<\/
+ * JSON字符串中不能包含控制字符和未经转义的引号和反斜杠 + * + * @param string 字符串 + * @return 适合在JSON中显示的字符串 + */ + public static String quote(final String string) { + return quote(string, true); + } + + /** + * 对所有双引号做转义处理(使用双反斜杠做转义)
+ * 为了能在HTML中较好的显示,会将</转义为<\/
+ * JSON字符串中不能包含控制字符和未经转义的引号和反斜杠 + * + * @param string 字符串 + * @param isWrap 是否使用双引号包装字符串 + * @return 适合在JSON中显示的字符串 + * @since 3.3.1 + */ + public static String quote(final String string, final boolean isWrap) { + return quote(string, new StringWriter(), isWrap).toString(); + } + + /** + * 对所有双引号做转义处理(使用双反斜杠做转义)
+ * 为了能在HTML中较好的显示,会将</转义为<\/
+ * JSON字符串中不能包含控制字符和未经转义的引号和反斜杠 + * + * @param str 字符串 + * @param writer Writer + * @return Writer + * @throws IORuntimeException IO异常 + */ + public static Writer quote(final String str, final Writer writer) throws IORuntimeException { + return quote(str, writer, true); + } + + /** + * 对所有双引号做转义处理(使用双反斜杠做转义)
+ * 为了能在HTML中较好的显示,会将</转义为<\/
+ * JSON字符串中不能包含控制字符和未经转义的引号和反斜杠 + * + * @param str 字符串 + * @param writer Writer + * @param isWrap 是否使用双引号包装字符串 + * @return Writer + * @throws IORuntimeException IO异常 + * @since 3.3.1 + */ + public static Writer quote(final String str, final Writer writer, final boolean isWrap) throws IORuntimeException { + try { + return doQuote(str, writer, isWrap); + } catch (IOException e) { + throw new IORuntimeException(e); + } + } + + /** + * 转义显示不可见字符 + * + * @param str 字符串 + * @return 转义后的字符串 + */ + public static String escape(final String str) { + if (StrUtil.isEmpty(str)) { + return str; + } + + final int len = str.length(); + final StringBuilder builder = new StringBuilder(len); + char c; + for (int i = 0; i < len; i++) { + c = str.charAt(i); + builder.append(escape(c)); + } + return builder.toString(); } /** @@ -286,4 +372,82 @@ public final class InternalJSONUtil { } return rawHashMap; } + + // --------------------------------------------------------------------------------------------- Private method start + /** + * 对所有双引号做转义处理(使用双反斜杠做转义)
+ * 为了能在HTML中较好的显示,会将</转义为<\/
+ * JSON字符串中不能包含控制字符和未经转义的引号和反斜杠 + * + * @param str 字符串 + * @param writer Writer + * @param isWrap 是否使用双引号包装字符串 + * @return Writer + * @throws IOException IO异常 + * @since 3.3.1 + */ + private static Writer doQuote(final String str, final Writer writer, final boolean isWrap) throws IOException { + if (StrUtil.isEmpty(str)) { + if (isWrap) { + writer.write("\"\""); + } + return writer; + } + + char c; // 当前字符 + final int len = str.length(); + if (isWrap) { + writer.write('"'); + } + for (int i = 0; i < len; i++) { + c = str.charAt(i); + switch (c) { + case '\\': + case '"': + writer.write("\\"); + writer.write(c); + break; + default: + writer.write(escape(c)); + } + } + if (isWrap) { + writer.write('"'); + } + return writer; + } + + /** + * 转义不可见字符
+ * 见:https://en.wikibooks.org/wiki/Unicode/Character_reference/0000-0FFF + * + * @param c 字符 + * @return 转义后的字符串 + */ + private static String escape(final char c) { + switch (c) { + case '\b': + return "\\b"; + case '\t': + return "\\t"; + case '\n': + return "\\n"; + case '\f': + return "\\f"; + case '\r': + return "\\r"; + default: + if (c < StrUtil.C_SPACE || // + (c >= '\u0080' && c <= '\u00a0') || // + (c >= '\u2000' && c <= '\u2010') || // + (c >= '\u2028' && c <= '\u202F') || // + (c >= '\u2066' && c <= '\u206F')// + ) { + return HexUtil.toUnicodeHex(c); + } else { + return Character.toString(c); + } + } + } + // --------------------------------------------------------------------------------------------- Private method end } diff --git a/hutool-json/src/main/java/cn/hutool/json/JSON.java b/hutool-json/src/main/java/cn/hutool/json/JSON.java index ce13eb351..79e510951 100755 --- a/hutool-json/src/main/java/cn/hutool/json/JSON.java +++ b/hutool-json/src/main/java/cn/hutool/json/JSON.java @@ -1,7 +1,7 @@ package cn.hutool.json; import cn.hutool.core.bean.BeanPath; -import cn.hutool.json.convert.JSONConverter; +import cn.hutool.json.convert.JSONConverterOld; import java.io.Serializable; import java.io.StringWriter; @@ -169,6 +169,6 @@ public interface JSON extends Cloneable, Serializable { * @since 4.3.2 */ default T toBean(final Type type) { - return JSONConverter.jsonConvert(type, this, getConfig()); + return JSONConverterOld.jsonConvert(type, this, getConfig()); } } diff --git a/hutool-json/src/main/java/cn/hutool/json/JSONArray.java b/hutool-json/src/main/java/cn/hutool/json/JSONArray.java index 69e0886da..29fcd1cb3 100755 --- a/hutool-json/src/main/java/cn/hutool/json/JSONArray.java +++ b/hutool-json/src/main/java/cn/hutool/json/JSONArray.java @@ -8,7 +8,7 @@ import cn.hutool.core.lang.mutable.MutableEntry; import cn.hutool.core.lang.mutable.MutableObj; import cn.hutool.core.text.StrJoiner; import cn.hutool.core.util.ObjUtil; -import cn.hutool.json.convert.JSONConverter; +import cn.hutool.json.convert.JSONConverterOld; import cn.hutool.json.mapper.ArrayMapper; import cn.hutool.json.serialize.JSONWriter; @@ -195,7 +195,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando @Override public T getByPath(final String expression, final Class resultType) { - return JSONConverter.jsonConvert(resultType, getByPath(expression), getConfig()); + return JSONConverterOld.jsonConvert(resultType, getByPath(expression), getConfig()); } /** diff --git a/hutool-json/src/main/java/cn/hutool/json/JSONGetter.java b/hutool-json/src/main/java/cn/hutool/json/JSONGetter.java index 0d614c4fa..6114a2790 100644 --- a/hutool-json/src/main/java/cn/hutool/json/JSONGetter.java +++ b/hutool-json/src/main/java/cn/hutool/json/JSONGetter.java @@ -3,7 +3,7 @@ package cn.hutool.json; import cn.hutool.core.convert.ConvertException; import cn.hutool.core.lang.getter.OptNullBasicTypeFromObjectGetter; import cn.hutool.core.util.ObjUtil; -import cn.hutool.json.convert.JSONConverter; +import cn.hutool.json.convert.JSONConverterOld; import java.time.LocalDateTime; import java.util.Date; @@ -55,7 +55,7 @@ public interface JSONGetter extends OptNullBasicTypeFromObjectGetter { * @since 4.2.2 */ default String getStrEscaped(final K key, final String defaultValue) { - return JSONUtil.escape(getStr(key, defaultValue)); + return InternalJSONUtil.escape(getStr(key, defaultValue)); } /** @@ -169,6 +169,6 @@ public interface JSONGetter extends OptNullBasicTypeFromObjectGetter { return null; } - return JSONConverter.jsonConvert(type, value, getConfig()); + return JSONConverterOld.jsonConvert(type, value, getConfig()); } } diff --git a/hutool-json/src/main/java/cn/hutool/json/JSONObject.java b/hutool-json/src/main/java/cn/hutool/json/JSONObject.java index 28df39714..95a75a919 100755 --- a/hutool-json/src/main/java/cn/hutool/json/JSONObject.java +++ b/hutool-json/src/main/java/cn/hutool/json/JSONObject.java @@ -5,7 +5,7 @@ import cn.hutool.core.lang.mutable.MutableEntry; import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapWrapper; import cn.hutool.core.util.ObjUtil; -import cn.hutool.json.convert.JSONConverter; +import cn.hutool.json.convert.JSONConverterOld; import cn.hutool.json.mapper.ObjectMapper; import cn.hutool.json.serialize.JSONWriter; @@ -185,7 +185,7 @@ public class JSONObject extends MapWrapper implements JSON, JSON @Override public T getByPath(final String expression, final Class resultType) { - return JSONConverter.jsonConvert(resultType, getByPath(expression), getConfig()); + return JSONConverterOld.jsonConvert(resultType, getByPath(expression), getConfig()); } /** @@ -287,7 +287,7 @@ public class JSONObject extends MapWrapper implements JSON, JSON } else if (object instanceof JSONArray) { ((JSONArray) object).set(value); } else { - this.set(key, JSONUtil.createArray(this.config).set(object).set(value)); + this.set(key, JSONUtil.ofArray(this.config).set(object).set(value)); } return this; } @@ -316,7 +316,7 @@ public class JSONObject extends MapWrapper implements JSON, JSON } else if (value instanceof Float) { this.set(key, (Float) value + 1); } else { - throw new JSONException("Unable to increment [" + JSONUtil.quote(key) + "]."); + throw new JSONException("Unable to increment [" + InternalJSONUtil.quote(key) + "]."); } return this; } diff --git a/hutool-json/src/main/java/cn/hutool/json/JSONSupport.java b/hutool-json/src/main/java/cn/hutool/json/JSONSupport.java index b4a3e7c2a..8660e849b 100644 --- a/hutool-json/src/main/java/cn/hutool/json/JSONSupport.java +++ b/hutool-json/src/main/java/cn/hutool/json/JSONSupport.java @@ -1,7 +1,7 @@ package cn.hutool.json; import cn.hutool.core.bean.BeanUtil; -import cn.hutool.json.convert.JSONConverter; +import cn.hutool.json.convert.JSONConverterOld; import cn.hutool.json.serialize.JSONDeserializer; import cn.hutool.json.serialize.JSONString; @@ -29,7 +29,7 @@ public class JSONSupport implements JSONString, JSONDeserializer { */ @Override public Object deserialize(final JSON json) { - final JSONSupport support = JSONConverter.jsonToBean(getClass(), json, false); + final JSONSupport support = JSONConverterOld.jsonToBean(getClass(), json, false); BeanUtil.copyProperties(support, this); return this; } diff --git a/hutool-json/src/main/java/cn/hutool/json/JSONUtil.java b/hutool-json/src/main/java/cn/hutool/json/JSONUtil.java index e22cfb5e5..a8ce84388 100755 --- a/hutool-json/src/main/java/cn/hutool/json/JSONUtil.java +++ b/hutool-json/src/main/java/cn/hutool/json/JSONUtil.java @@ -1,13 +1,11 @@ package cn.hutool.json; -import cn.hutool.core.codec.HexUtil; +import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.IORuntimeException; -import cn.hutool.core.io.file.FileReader; -import cn.hutool.core.map.MapWrapper; import cn.hutool.core.reflect.TypeReference; import cn.hutool.core.text.StrUtil; -import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ObjUtil; +import cn.hutool.json.convert.JSONConverter; import cn.hutool.json.serialize.GlobalSerializeMapping; import cn.hutool.json.serialize.JSONArraySerializer; import cn.hutool.json.serialize.JSONDeserializer; @@ -16,11 +14,10 @@ import cn.hutool.json.xml.JSONXMLUtil; import java.io.File; import java.io.IOException; -import java.io.StringWriter; +import java.io.Reader; import java.io.Writer; import java.lang.reflect.Type; import java.nio.charset.Charset; -import java.util.Iterator; import java.util.List; /** @@ -37,7 +34,7 @@ public class JSONUtil { * * @return JSONObject */ - public static JSONObject createObj() { + public static JSONObject ofObj() { return new JSONObject(); } @@ -48,7 +45,7 @@ public class JSONUtil { * @return JSONObject * @since 5.2.5 */ - public static JSONObject createObj(final JSONConfig config) { + public static JSONObject ofObj(final JSONConfig config) { return new JSONObject(config); } @@ -57,7 +54,7 @@ public class JSONUtil { * * @return JSONArray */ - public static JSONArray createArray() { + public static JSONArray ofArray() { return new JSONArray(); } @@ -68,7 +65,7 @@ public class JSONUtil { * @return JSONArray * @since 5.2.5 */ - public static JSONArray createArray(final JSONConfig config) { + public static JSONArray ofArray(final JSONConfig config) { return new JSONArray(config); } @@ -131,18 +128,6 @@ public class JSONUtil { return new JSONArray(arrayOrCollection, config); } - /** - * JSON字符串转JSONArray - * - * @param arrayOrCollection 数组或集合对象 - * @param ignoreNullValue 是否忽略空值 - * @return JSONArray - * @since 3.2.3 - */ - public static JSONArray parseArray(final Object arrayOrCollection, final boolean ignoreNullValue) { - return new JSONArray(arrayOrCollection, JSONConfig.of().setIgnoreNullValue(ignoreNullValue)); - } - /** * 转换对象为JSON,如果用户不配置JSONConfig,则JSON的有序与否与传入对象有关。
* 支持的对象: @@ -156,7 +141,7 @@ public class JSONUtil { * @return JSON */ public static JSON parse(final Object obj) { - return parse(obj, null); + return JSONConverter.INSTANCE.convert(obj); } /** @@ -174,25 +159,7 @@ public class JSONUtil { * @since 5.3.1 */ public static JSON parse(final Object obj, final JSONConfig config) { - if (null == obj) { - return null; - } - final JSON json; - if (obj instanceof JSON) { - json = (JSON) obj; - } else if (obj instanceof CharSequence) { - final String jsonStr = StrUtil.trim((CharSequence) obj); - json = isTypeJSONArray(jsonStr) ? parseArray(jsonStr, config) : parseObj(jsonStr, config); - } else if (obj instanceof MapWrapper) { - // MapWrapper实现了Iterable会被当作JSONArray,此处做修正 - json = parseObj(obj, config); - } else if (obj instanceof Iterable || obj instanceof Iterator || ArrayUtil.isArray(obj)) {// 列表 - json = parseArray(obj, config); - } else {// 对象 - json = parseObj(obj, config); - } - - return json; + return JSONConverter.of(config).convert(obj); } /** @@ -204,11 +171,9 @@ public class JSONUtil { public static JSONObject parseFromXml(final String xmlStr) { return JSONXMLUtil.toJSONObject(xmlStr); } - // -------------------------------------------------------------------- Parse end // -------------------------------------------------------------------- Read start - /** * 读取JSON * @@ -218,7 +183,11 @@ public class JSONUtil { * @throws IORuntimeException IO异常 */ public static JSON readJSON(final File file, final Charset charset) throws IORuntimeException { - return parse(FileReader.of(file, charset).readString()); + try (final Reader reader = FileUtil.getReader(file, charset)) { + return parse(reader); + } catch (final IOException e) { + throw new IORuntimeException(e); + } } /** @@ -230,7 +199,11 @@ public class JSONUtil { * @throws IORuntimeException IO异常 */ public static JSONObject readJSONObject(final File file, final Charset charset) throws IORuntimeException { - return parseObj(FileReader.of(file, charset).readString()); + try (final Reader reader = FileUtil.getReader(file, charset)) { + return parseObj(reader); + } catch (final IOException e) { + throw new IORuntimeException(e); + } } /** @@ -242,7 +215,11 @@ public class JSONUtil { * @throws IORuntimeException IO异常 */ public static JSONArray readJSONArray(final File file, final Charset charset) throws IORuntimeException { - return parseArray(FileReader.of(file, charset).readString()); + try (final Reader reader = FileUtil.getReader(file, charset)) { + return parseArray(reader); + } catch (final IOException e) { + throw new IORuntimeException(e); + } } // -------------------------------------------------------------------- Read end @@ -298,7 +275,7 @@ public class JSONUtil { if (null == json) { return null; } - return json.toJSONString(4); + return json.toStringPretty(); } /** @@ -365,6 +342,18 @@ public class JSONUtil { public static String toXmlStr(final JSON json) { return JSONXMLUtil.toXml(json); } + + /** + * XML转JSONObject
+ * 转换过程中一些信息可能会丢失,JSON中无法区分节点和属性,相同的节点将被处理为JSONArray。 + * + * @param xml XML字符串 + * @return JSONObject + * @since 4.0.8 + */ + public static JSONObject xmlToJson(final String xml) { + return JSONXMLUtil.toJSONObject(xml); + } // -------------------------------------------------------------------- toString end // -------------------------------------------------------------------- toBean start @@ -567,116 +556,6 @@ public class JSONUtil { json.putByPath(expression, value); } - /** - * 对所有双引号做转义处理(使用双反斜杠做转义)
- * 为了能在HTML中较好的显示,会将</转义为<\/
- * JSON字符串中不能包含控制字符和未经转义的引号和反斜杠 - * - * @param string 字符串 - * @return 适合在JSON中显示的字符串 - */ - public static String quote(final String string) { - return quote(string, true); - } - - /** - * 对所有双引号做转义处理(使用双反斜杠做转义)
- * 为了能在HTML中较好的显示,会将</转义为<\/
- * JSON字符串中不能包含控制字符和未经转义的引号和反斜杠 - * - * @param string 字符串 - * @param isWrap 是否使用双引号包装字符串 - * @return 适合在JSON中显示的字符串 - * @since 3.3.1 - */ - public static String quote(final String string, final boolean isWrap) { - final StringWriter sw = new StringWriter(); - try { - return quote(string, sw, isWrap).toString(); - } catch (final IOException ignored) { - // will never happen - we are writing to a string writer - return StrUtil.EMPTY; - } - } - - /** - * 对所有双引号做转义处理(使用双反斜杠做转义)
- * 为了能在HTML中较好的显示,会将</转义为<\/
- * JSON字符串中不能包含控制字符和未经转义的引号和反斜杠 - * - * @param str 字符串 - * @param writer Writer - * @return Writer - * @throws IOException IO异常 - */ - public static Writer quote(final String str, final Writer writer) throws IOException { - return quote(str, writer, true); - } - - /** - * 对所有双引号做转义处理(使用双反斜杠做转义)
- * 为了能在HTML中较好的显示,会将</转义为<\/
- * JSON字符串中不能包含控制字符和未经转义的引号和反斜杠 - * - * @param str 字符串 - * @param writer Writer - * @param isWrap 是否使用双引号包装字符串 - * @return Writer - * @throws IOException IO异常 - * @since 3.3.1 - */ - public static Writer quote(final String str, final Writer writer, final boolean isWrap) throws IOException { - if (StrUtil.isEmpty(str)) { - if (isWrap) { - writer.write("\"\""); - } - return writer; - } - - char c; // 当前字符 - final int len = str.length(); - if (isWrap) { - writer.write('"'); - } - for (int i = 0; i < len; i++) { - c = str.charAt(i); - switch (c) { - case '\\': - case '"': - writer.write("\\"); - writer.write(c); - break; - default: - writer.write(escape(c)); - } - } - if (isWrap) { - writer.write('"'); - } - return writer; - } - - /** - * 转义显示不可见字符 - * - * @param str 字符串 - * @return 转义后的字符串 - */ - public static String escape(final String str) { - if (StrUtil.isEmpty(str)) { - return str; - } - - final int len = str.length(); - final StringBuilder builder = new StringBuilder(len); - char c; - for (int i = 0; i < len; i++) { - c = str.charAt(i); - builder.append(escape(c)); - } - return builder.toString(); - } - /** * 格式化JSON字符串,此方法并不严格检查JSON的格式正确与否 * @@ -727,18 +606,6 @@ public class JSONUtil { return StrUtil.isWrap(StrUtil.trim(str), '[', ']'); } - /** - * XML转JSONObject
- * 转换过程中一些信息可能会丢失,JSON中无法区分节点和属性,相同的节点将被处理为JSONArray。 - * - * @param xml XML字符串 - * @return JSONObject - * @since 4.0.8 - */ - public static JSONObject xmlToJson(final String xml) { - return JSONXMLUtil.toJSONObject(xml); - } - /** * 加入自定义的序列化器 * @@ -774,40 +641,4 @@ public class JSONUtil { public static void putDeserializer(final Type type, final JSONDeserializer deserializer) { GlobalSerializeMapping.putDeserializer(type, deserializer); } - - // --------------------------------------------------------------------------------------------- Private method start - - /** - * 转义不可见字符
- * 见:https://en.wikibooks.org/wiki/Unicode/Character_reference/0000-0FFF - * - * @param c 字符 - * @return 转义后的字符串 - */ - private static String escape(final char c) { - switch (c) { - case '\b': - return "\\b"; - case '\t': - return "\\t"; - case '\n': - return "\\n"; - case '\f': - return "\\f"; - case '\r': - return "\\r"; - default: - if (c < StrUtil.C_SPACE || // - (c >= '\u0080' && c <= '\u00a0') || // - (c >= '\u2000' && c <= '\u2010') || // - (c >= '\u2028' && c <= '\u202F') || // - (c >= '\u2066' && c <= '\u206F')// - ) { - return HexUtil.toUnicodeHex(c); - } else { - return Character.toString(c); - } - } - } - // --------------------------------------------------------------------------------------------- Private method end } diff --git a/hutool-json/src/main/java/cn/hutool/json/convert/JSONConverter.java b/hutool-json/src/main/java/cn/hutool/json/convert/JSONConverter.java index d42da472b..8422c42b7 100644 --- a/hutool-json/src/main/java/cn/hutool/json/convert/JSONConverter.java +++ b/hutool-json/src/main/java/cn/hutool/json/convert/JSONConverter.java @@ -1,194 +1,90 @@ package cn.hutool.json.convert; -import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.convert.ConvertException; import cn.hutool.core.convert.Converter; -import cn.hutool.core.convert.CompositeConverter; -import cn.hutool.core.convert.impl.BeanConverter; -import cn.hutool.core.convert.impl.DateConverter; -import cn.hutool.core.convert.impl.TemporalAccessorConverter; -import cn.hutool.core.reflect.ConstructorUtil; -import cn.hutool.core.reflect.TypeUtil; +import cn.hutool.core.map.MapWrapper; import cn.hutool.core.text.StrUtil; -import cn.hutool.core.util.ObjUtil; -import cn.hutool.json.InternalJSONUtil; +import cn.hutool.core.util.ArrayUtil; import cn.hutool.json.JSON; import cn.hutool.json.JSONArray; import cn.hutool.json.JSONConfig; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; -import cn.hutool.json.serialize.GlobalSerializeMapping; -import cn.hutool.json.serialize.JSONDeserializer; import java.lang.reflect.Type; -import java.time.temporal.TemporalAccessor; -import java.util.Date; +import java.util.Iterator; /** - * JSON转换器 + * JSON转换器,实现Object对象转换为{@link JSON},支持的对象: + *
    + *
  • String: 转换为相应的对象
  • + *
  • Array、Iterable、Iterator:转换为JSONArray
  • + *
  • Bean对象:转为JSONObject
  • + *
* * @author looly - * @since 4.2.2 + * @since 6.0.0 */ public class JSONConverter implements Converter { + public static final JSONConverter INSTANCE = new JSONConverter(null); - public static JSONConverter INSTANCE = new JSONConverter(); + /** + * 创建JSON转换器 + * + * @param config JSON配置 + * @return JSONConverter + */ + public static JSONConverter of(final JSONConfig config) { + return new JSONConverter(config); + } - private static final CompositeConverter registry; - static { - // 注册到转换中心 - registry = new CompositeConverter(); - registry.putCustom(JSON.class, INSTANCE); - registry.putCustom(JSONObject.class, INSTANCE); - registry.putCustom(JSONArray.class, INSTANCE); + private final JSONConfig config; + + /** + * 构造 + * + * @param config JSON配置 + */ + public JSONConverter(final JSONConfig config) { + this.config = config; + } + + /** + * 实现Object对象转换为{@link JSON},支持的对象: + *
    + *
  • String: 转换为相应的对象
  • + *
  • Array、Iterable、Iterator:转换为JSONArray
  • + *
  • Bean对象:转为JSONObject
  • + *
+ * + * @param obj 被转换的对象 + * @return 转换后的对象 + * @throws ConvertException 转换异常 + */ + public JSON convert(final Object obj) throws ConvertException { + return (JSON) convert(null, obj); } @Override - public Object convert(final Type targetType, final Object value) throws ConvertException { - return JSONUtil.parse(value); - } - - /** - * 转换值为指定类型,可选是否不抛异常转换
- * 当转换失败时返回默认值 - * - * @param 目标类型 - * @param type 目标类型 - * @param value 值 - * @param defaultValue 默认值 - * @param quietly 是否静默转换,true不抛异常 - * @return 转换后的值 - * @since 5.3.2 - */ - public static T convertWithCheck(final Type type, final Object value, final T defaultValue, final boolean quietly) { - try { - return registry.convert(type, value, defaultValue); - } catch (final Exception e) { - if(quietly){ - return defaultValue; - } - throw e; - } - } - - /** - * JSON递归转换
- * 首先尝试JDK类型转换,如果失败尝试JSON转Bean
- * 如果遇到{@link JSONDeserializer},则调用其{@link JSONDeserializer#deserialize(JSON)}方法转换。 - * - * @param 转换后的对象类型 - * @param targetType 目标类型 - * @param value 值 - * @param config JSON配置项 - * @return 目标类型的值 - * @throws ConvertException 转换失败 - */ - @SuppressWarnings("unchecked") - public static T jsonConvert(final Type targetType, final Object value, final JSONConfig config) throws ConvertException { - if (null == value) { + public Object convert(final Type targetType, final Object obj) throws ConvertException { + if (null == obj) { return null; } - - // since 5.7.8,增加自定义Bean反序列化接口和特殊对象的自定义转换 - if (targetType instanceof Class) { - final Class targetClass = (Class) targetType; - if (targetClass.isInstance(value)) { - return (T) value; - } else if (JSONDeserializer.class.isAssignableFrom(targetClass)) { - // 自定义反序列化 - if (value instanceof JSON) { - final JSONDeserializer target = (JSONDeserializer) ConstructorUtil.newInstanceIfPossible(targetClass); - if (null == target) { - throw new ConvertException("Can not instance target: [{}]", targetType); - } - return target.deserialize((JSON) value); - } - } else if (targetClass.isAssignableFrom(Date.class) || targetClass.isAssignableFrom(TemporalAccessor.class)) { - // 用户指定了日期格式,获取日期属性时使用对应格式 - final String valueStr = convertWithCheck(String.class, value, null, true); - if (null == valueStr) { - return null; - } - - // 日期转换,支持自定义日期格式 - final String format = getDateFormat(config); - if (null != format) { - if (targetClass.isAssignableFrom(Date.class)) { - return (T) new DateConverter(format).convert(targetClass, valueStr); - } else { - return (T) new TemporalAccessorConverter(format).convert(targetClass, valueStr); - } - } - } + final JSON json; + if (obj instanceof JSON) { + json = (JSON) obj; + } else if (obj instanceof CharSequence) { + final String jsonStr = StrUtil.trim((CharSequence) obj); + json = JSONUtil.isTypeJSONArray(jsonStr) ? new JSONArray(jsonStr, config) : new JSONObject(jsonStr, config); + } else if (obj instanceof MapWrapper) { + // MapWrapper实现了Iterable会被当作JSONArray,此处做修正 + json = new JSONObject(obj, config); + } else if (obj instanceof Iterable || obj instanceof Iterator || ArrayUtil.isArray(obj)) {// 列表 + json = new JSONArray(obj, config); + } else {// 对象 + json = new JSONObject(obj, config); } - return jsonToBean(targetType, value, null != config && config.isIgnoreError()); - } - - /** - * JSON递归转换为Bean
- * 首先尝试JDK类型转换,如果失败尝试JSON转Bean - * - * @param 转换后的对象类型 - * @param targetType 目标类型 - * @param value 值,JSON格式 - * @param ignoreError 是否忽略转换错误 - * @return 目标类型的值 - * @throws ConvertException 转换失败 - * @since 5.7.10 - */ - @SuppressWarnings("unchecked") - public static T jsonToBean(final Type targetType, final Object value, final boolean ignoreError) throws ConvertException { - if (null == value) { - return null; - } - - if (value instanceof JSON) { - final JSON valueJson = (JSON) value; - // 全局自定义反序列化 - final JSONDeserializer deserializer = GlobalSerializeMapping.getDeserializer(targetType); - if (null != deserializer) { - return (T) deserializer.deserialize(valueJson); - } - - // issue#2212@Github - // 在JSONObject转Bean时,读取JSONObject本身的配置文件 - if (targetType instanceof Class && BeanUtil.hasSetter((Class) targetType)) { - final JSONConfig config = valueJson.getConfig(); - final Converter converter = new BeanConverter(InternalJSONUtil.toCopyOptions(config).setIgnoreError(ignoreError)); - return ignoreError ? converter.convert(targetType, value, null) - : (T) converter.convert(targetType, value); - } - } - - final T targetValue = convertWithCheck(targetType, value, null, ignoreError); - - if (null == targetValue && false == ignoreError) { - if (StrUtil.isBlankIfStr(value)) { - // 对于传入空字符串的情况,如果转换的目标对象是非字符串或非原始类型,转换器会返回false。 - // 此处特殊处理,认为返回null属于正常情况 - return null; - } - - throw new ConvertException("Can not convert {} to type {}", value, ObjUtil.defaultIfNull(TypeUtil.getClass(targetType), targetType)); - } - - return targetValue; - } - - /** - * 获取配置文件中的日期格式,无格式返回{@code null} - * - * @param config JSON配置 - * @return 日期格式,无返回{@code null} - */ - private static String getDateFormat(final JSONConfig config) { - if (null != config) { - final String format = config.getDateFormat(); - if (StrUtil.isNotBlank(format)) { - return format; - } - } - return null; + return json; } } diff --git a/hutool-json/src/main/java/cn/hutool/json/convert/JSONConverterOld.java b/hutool-json/src/main/java/cn/hutool/json/convert/JSONConverterOld.java new file mode 100644 index 000000000..68c4a4d13 --- /dev/null +++ b/hutool-json/src/main/java/cn/hutool/json/convert/JSONConverterOld.java @@ -0,0 +1,194 @@ +package cn.hutool.json.convert; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.convert.ConvertException; +import cn.hutool.core.convert.Converter; +import cn.hutool.core.convert.CompositeConverter; +import cn.hutool.core.convert.impl.BeanConverter; +import cn.hutool.core.convert.impl.DateConverter; +import cn.hutool.core.convert.impl.TemporalAccessorConverter; +import cn.hutool.core.reflect.ConstructorUtil; +import cn.hutool.core.reflect.TypeUtil; +import cn.hutool.core.text.StrUtil; +import cn.hutool.core.util.ObjUtil; +import cn.hutool.json.InternalJSONUtil; +import cn.hutool.json.JSON; +import cn.hutool.json.JSONArray; +import cn.hutool.json.JSONConfig; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import cn.hutool.json.serialize.GlobalSerializeMapping; +import cn.hutool.json.serialize.JSONDeserializer; + +import java.lang.reflect.Type; +import java.time.temporal.TemporalAccessor; +import java.util.Date; + +/** + * JSON转换器 + * + * @author looly + * @since 4.2.2 + */ +public class JSONConverterOld implements Converter { + + public static final JSONConverterOld INSTANCE = new JSONConverterOld(); + + private static final CompositeConverter registry; + static { + // 注册到转换中心 + registry = new CompositeConverter(); + registry.putCustom(JSON.class, INSTANCE); + registry.putCustom(JSONObject.class, INSTANCE); + registry.putCustom(JSONArray.class, INSTANCE); + } + + @Override + public Object convert(final Type targetType, final Object value) throws ConvertException { + return JSONUtil.parse(value); + } + + /** + * 转换值为指定类型,可选是否不抛异常转换
+ * 当转换失败时返回默认值 + * + * @param 目标类型 + * @param type 目标类型 + * @param value 值 + * @param defaultValue 默认值 + * @param quietly 是否静默转换,true不抛异常 + * @return 转换后的值 + * @since 5.3.2 + */ + public static T convertWithCheck(final Type type, final Object value, final T defaultValue, final boolean quietly) { + try { + return registry.convert(type, value, defaultValue); + } catch (final Exception e) { + if(quietly){ + return defaultValue; + } + throw e; + } + } + + /** + * JSON递归转换
+ * 首先尝试JDK类型转换,如果失败尝试JSON转Bean
+ * 如果遇到{@link JSONDeserializer},则调用其{@link JSONDeserializer#deserialize(JSON)}方法转换。 + * + * @param 转换后的对象类型 + * @param targetType 目标类型 + * @param value 值 + * @param config JSON配置项 + * @return 目标类型的值 + * @throws ConvertException 转换失败 + */ + @SuppressWarnings("unchecked") + public static T jsonConvert(final Type targetType, final Object value, final JSONConfig config) throws ConvertException { + if (null == value) { + return null; + } + + // since 5.7.8,增加自定义Bean反序列化接口和特殊对象的自定义转换 + if (targetType instanceof Class) { + final Class targetClass = (Class) targetType; + if (targetClass.isInstance(value)) { + return (T) value; + } else if (JSONDeserializer.class.isAssignableFrom(targetClass)) { + // 自定义反序列化 + if (value instanceof JSON) { + final JSONDeserializer target = (JSONDeserializer) ConstructorUtil.newInstanceIfPossible(targetClass); + if (null == target) { + throw new ConvertException("Can not instance target: [{}]", targetType); + } + return target.deserialize((JSON) value); + } + } else if (targetClass.isAssignableFrom(Date.class) || targetClass.isAssignableFrom(TemporalAccessor.class)) { + // 用户指定了日期格式,获取日期属性时使用对应格式 + final String valueStr = convertWithCheck(String.class, value, null, true); + if (null == valueStr) { + return null; + } + + // 日期转换,支持自定义日期格式 + final String format = getDateFormat(config); + if (null != format) { + if (targetClass.isAssignableFrom(Date.class)) { + return (T) new DateConverter(format).convert(targetClass, valueStr); + } else { + return (T) new TemporalAccessorConverter(format).convert(targetClass, valueStr); + } + } + } + } + + return jsonToBean(targetType, value, null != config && config.isIgnoreError()); + } + + /** + * JSON递归转换为Bean
+ * 首先尝试JDK类型转换,如果失败尝试JSON转Bean + * + * @param 转换后的对象类型 + * @param targetType 目标类型 + * @param value 值,JSON格式 + * @param ignoreError 是否忽略转换错误 + * @return 目标类型的值 + * @throws ConvertException 转换失败 + * @since 5.7.10 + */ + @SuppressWarnings("unchecked") + public static T jsonToBean(final Type targetType, final Object value, final boolean ignoreError) throws ConvertException { + if (null == value) { + return null; + } + + if (value instanceof JSON) { + final JSON valueJson = (JSON) value; + // 全局自定义反序列化 + final JSONDeserializer deserializer = GlobalSerializeMapping.getDeserializer(targetType); + if (null != deserializer) { + return (T) deserializer.deserialize(valueJson); + } + + // issue#2212@Github + // 在JSONObject转Bean时,读取JSONObject本身的配置文件 + if (targetType instanceof Class && BeanUtil.hasSetter((Class) targetType)) { + final JSONConfig config = valueJson.getConfig(); + final Converter converter = new BeanConverter(InternalJSONUtil.toCopyOptions(config).setIgnoreError(ignoreError)); + return ignoreError ? converter.convert(targetType, value, null) + : (T) converter.convert(targetType, value); + } + } + + final T targetValue = convertWithCheck(targetType, value, null, ignoreError); + + if (null == targetValue && false == ignoreError) { + if (StrUtil.isBlankIfStr(value)) { + // 对于传入空字符串的情况,如果转换的目标对象是非字符串或非原始类型,转换器会返回false。 + // 此处特殊处理,认为返回null属于正常情况 + return null; + } + + throw new ConvertException("Can not convert {} to type {}", value, ObjUtil.defaultIfNull(TypeUtil.getClass(targetType), targetType)); + } + + return targetValue; + } + + /** + * 获取配置文件中的日期格式,无格式返回{@code null} + * + * @param config JSON配置 + * @return 日期格式,无返回{@code null} + */ + private static String getDateFormat(final JSONConfig config) { + if (null != config) { + final String format = config.getDateFormat(); + if (StrUtil.isNotBlank(format)) { + return format; + } + } + return null; + } +} diff --git a/hutool-json/src/main/java/cn/hutool/json/convert/JSONDeserializerConverter.java b/hutool-json/src/main/java/cn/hutool/json/convert/JSONDeserializerConverter.java index 6269bad2b..c23e8799a 100644 --- a/hutool-json/src/main/java/cn/hutool/json/convert/JSONDeserializerConverter.java +++ b/hutool-json/src/main/java/cn/hutool/json/convert/JSONDeserializerConverter.java @@ -16,7 +16,7 @@ public class JSONDeserializerConverter extends AbstractConverter { private static final long serialVersionUID = 1L; @Override - protected Object convertInternal(Class targetClass, Object value) { + protected Object convertInternal(final Class targetClass, final Object value) { // 自定义反序列化 if (value instanceof JSON) { final JSONDeserializer target = (JSONDeserializer) ConstructorUtil.newInstanceIfPossible(targetClass); diff --git a/hutool-json/src/main/java/cn/hutool/json/convert/package-info.java b/hutool-json/src/main/java/cn/hutool/json/convert/package-info.java new file mode 100644 index 000000000..e012cc89b --- /dev/null +++ b/hutool-json/src/main/java/cn/hutool/json/convert/package-info.java @@ -0,0 +1,7 @@ +/** + * JSON中对象、值类型转换封装 + * + * @author Looly + * @since 6.0.0 + */ +package cn.hutool.json.convert; diff --git a/hutool-json/src/main/java/cn/hutool/json/serialize/DateJSONString.java b/hutool-json/src/main/java/cn/hutool/json/serialize/DateJSONString.java index efdad9c4f..1a68796c2 100644 --- a/hutool-json/src/main/java/cn/hutool/json/serialize/DateJSONString.java +++ b/hutool-json/src/main/java/cn/hutool/json/serialize/DateJSONString.java @@ -5,8 +5,8 @@ import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.TemporalAccessorUtil; import cn.hutool.core.date.format.GlobalCustomFormat; import cn.hutool.core.text.StrUtil; +import cn.hutool.json.InternalJSONUtil; import cn.hutool.json.JSONConfig; -import cn.hutool.json.JSONUtil; import java.time.temporal.TemporalAccessor; import java.util.Calendar; @@ -55,7 +55,7 @@ public class DateJSONString implements JSONString { return dateStr; } //用户定义了日期格式 - return JSONUtil.quote(dateStr); + return InternalJSONUtil.quote(dateStr); } //默认使用时间戳 diff --git a/hutool-json/src/main/java/cn/hutool/json/serialize/JSONWriter.java b/hutool-json/src/main/java/cn/hutool/json/serialize/JSONWriter.java index b9df12106..9e97ffa8d 100755 --- a/hutool-json/src/main/java/cn/hutool/json/serialize/JSONWriter.java +++ b/hutool-json/src/main/java/cn/hutool/json/serialize/JSONWriter.java @@ -8,10 +8,10 @@ import cn.hutool.core.io.IORuntimeException; import cn.hutool.core.math.NumberUtil; import cn.hutool.core.text.StrUtil; import cn.hutool.core.util.CharUtil; +import cn.hutool.json.InternalJSONUtil; import cn.hutool.json.JSON; import cn.hutool.json.JSONConfig; import cn.hutool.json.JSONException; -import cn.hutool.json.JSONUtil; import java.io.IOException; import java.io.Writer; @@ -137,7 +137,7 @@ public class JSONWriter extends Writer { // 换行缩进 //noinspection resource writeLF().writeSpace(indentFactor + indent); - return writeRaw(JSONUtil.quote(key)); + return writeRaw(InternalJSONUtil.quote(key)); } /** @@ -300,11 +300,7 @@ public class JSONWriter extends Writer { * @param csq 字符串 */ private void writeQuoteStrValue(final String csq) { - try { - JSONUtil.quote(csq, writer); - } catch (final IOException e) { - throw new IORuntimeException(e); - } + InternalJSONUtil.quote(csq, writer); } /** @@ -386,7 +382,7 @@ public class JSONWriter extends Writer { return dateStr; } //用户定义了日期格式 - return JSONUtil.quote(dateStr); + return InternalJSONUtil.quote(dateStr); } //默认使用时间戳 diff --git a/hutool-json/src/test/java/cn/hutool/json/CustomSerializeTest.java b/hutool-json/src/test/java/cn/hutool/json/CustomSerializeTest.java index a8a339053..e22a07f57 100644 --- a/hutool-json/src/test/java/cn/hutool/json/CustomSerializeTest.java +++ b/hutool-json/src/test/java/cn/hutool/json/CustomSerializeTest.java @@ -29,7 +29,7 @@ public class CustomSerializeTest { final CustomBean customBean = new CustomBean(); customBean.name = "testName"; - final JSONObject obj = JSONUtil.createObj().set("customBean", customBean); + final JSONObject obj = JSONUtil.ofObj().set("customBean", customBean); Assert.assertEquals("testName", obj.getJSONObject("customBean").getStr("customName")); } diff --git a/hutool-json/src/test/java/cn/hutool/json/IssueI59LW4Test.java b/hutool-json/src/test/java/cn/hutool/json/IssueI59LW4Test.java index 360517388..f63094ab3 100644 --- a/hutool-json/src/test/java/cn/hutool/json/IssueI59LW4Test.java +++ b/hutool-json/src/test/java/cn/hutool/json/IssueI59LW4Test.java @@ -6,7 +6,7 @@ import org.junit.Test; public class IssueI59LW4Test { @Test public void bytesTest(){ - final JSONObject jsonObject = JSONUtil.createObj().set("bytes", new byte[]{1}); + final JSONObject jsonObject = JSONUtil.ofObj().set("bytes", new byte[]{1}); Assert.assertEquals("{\"bytes\":[1]}", jsonObject.toString()); final byte[] bytes = jsonObject.getBytes("bytes"); @@ -15,7 +15,7 @@ public class IssueI59LW4Test { @Test public void bytesInJSONArrayTest(){ - final JSONArray jsonArray = JSONUtil.createArray().set(new byte[]{1}); + final JSONArray jsonArray = JSONUtil.ofArray().set(new byte[]{1}); Assert.assertEquals("[[1]]", jsonArray.toString()); final byte[] bytes = jsonArray.getBytes(0); diff --git a/hutool-json/src/test/java/cn/hutool/json/JSONArrayTest.java b/hutool-json/src/test/java/cn/hutool/json/JSONArrayTest.java index a88bfb8e2..4e366e50b 100755 --- a/hutool-json/src/test/java/cn/hutool/json/JSONArrayTest.java +++ b/hutool-json/src/test/java/cn/hutool/json/JSONArrayTest.java @@ -22,12 +22,11 @@ import java.util.Map; * JSONArray单元测试 * * @author Looly - * */ public class JSONArrayTest { @Test() - public void createJSONArrayFromJSONObjectTest(){ + public void createJSONArrayFromJSONObjectTest() { // JSONObject实现了Iterable接口,可以转换为JSONArray final JSONObject jsonObject = new JSONObject(); @@ -41,7 +40,7 @@ public class JSONArrayTest { } @Test - public void addNullTest(){ + public void addNullTest() { final List aaa = ListUtil.view("aaa", null); final String jsonStr = JSONUtil.toJsonStr(JSONUtil.parse(aaa, JSONConfig.of().setIgnoreNullValue(false))); @@ -51,7 +50,7 @@ public class JSONArrayTest { @Test public void addTest() { // 方法1 - final JSONArray array = JSONUtil.createArray(); + final JSONArray array = JSONUtil.ofArray(); // 方法2 // JSONArray array = new JSONArray(); array.add("value1"); @@ -75,12 +74,12 @@ public class JSONArrayTest { Assert.assertFalse(jsonArray.getJSONObject(1).containsKey("result")); // 不忽略null,则null的键值对被保留 - jsonArray = JSONUtil.parseArray(jsonStr, false); + jsonArray = JSONUtil.parseArray(jsonStr, JSONConfig.of().setIgnoreNullValue(false)); Assert.assertTrue(jsonArray.getJSONObject(1).containsKey("result")); } @Test - public void parseFileTest() { + public void readJSONArrayFromFileTest() { final JSONArray array = JSONUtil.readJSONArray(FileUtil.file("exam_test.json"), CharsetUtil.UTF_8); final JSONObject obj0 = array.getJSONObject(0); @@ -175,11 +174,12 @@ public class JSONArrayTest { } @Test(expected = ConvertException.class) - public void toListWithErrorTest(){ + public void toListWithErrorTest() { final String json = "[['aaa',{'akey':'avalue','bkey':'bvalue'}]]"; final JSONArray ja = JSONUtil.parseArray(json); - ja.toBean(new TypeReference>>() {}); + ja.toBean(new TypeReference>>() { + }); } @Test @@ -209,7 +209,7 @@ public class JSONArrayTest { } @Test - public void getByPathTest(){ + public void getByPathTest() { final String jsonStr = "[{\"id\": \"1\",\"name\": \"a\"},{\"id\": \"2\",\"name\": \"b\"}]"; final JSONArray jsonArray = JSONUtil.parseArray(jsonStr); Assert.assertEquals("b", jsonArray.getByPath("[1].name")); @@ -217,7 +217,7 @@ public class JSONArrayTest { } @Test - public void putToIndexTest(){ + public void putToIndexTest() { JSONArray jsonArray = new JSONArray(); jsonArray.set(3, "test"); // 默认忽略null值,因此空位无值,只有一个值 @@ -231,7 +231,7 @@ public class JSONArrayTest { // https://github.com/dromara/hutool/issues/1858 @Test - public void putTest2(){ + public void putTest2() { final JSONArray jsonArray = new JSONArray(); jsonArray.put(0, 1); Assert.assertEquals(1, jsonArray.size()); @@ -253,8 +253,8 @@ public class JSONArrayTest { } @Test - public void filterIncludeTest(){ - final JSONArray json1 = JSONUtil.createArray() + public void filterIncludeTest() { + final JSONArray json1 = JSONUtil.ofArray() .set("value1") .set("value2") .set("value3") @@ -265,8 +265,8 @@ public class JSONArrayTest { } @Test - public void filterExcludeTest(){ - final JSONArray json1 = JSONUtil.createArray() + public void filterExcludeTest() { + final JSONArray json1 = JSONUtil.ofArray() .set("value1") .set("value2") .set("value3") @@ -277,8 +277,8 @@ public class JSONArrayTest { } @Test - public void putNullTest(){ - final JSONArray array = JSONUtil.createArray(JSONConfig.of().setIgnoreNullValue(false)); + public void putNullTest() { + final JSONArray array = JSONUtil.ofArray(JSONConfig.of().setIgnoreNullValue(false)); array.set(null); Assert.assertEquals("[null]", array.toString()); @@ -299,7 +299,7 @@ public class JSONArrayTest { //noinspection MismatchedQueryAndUpdateOfCollection final JSONArray array = new JSONArray(jsonArr, null, (mutable) -> { final JSONObject o = new JSONObject(mutable.get()); - if("111".equals(o.getStr("id"))){ + if ("111".equals(o.getStr("id"))) { o.set("name", "test1_edit"); } mutable.set(o); diff --git a/hutool-json/src/test/java/cn/hutool/json/JSONNullTest.java b/hutool-json/src/test/java/cn/hutool/json/JSONNullTest.java index 9f3783449..d14eb7d5e 100644 --- a/hutool-json/src/test/java/cn/hutool/json/JSONNullTest.java +++ b/hutool-json/src/test/java/cn/hutool/json/JSONNullTest.java @@ -35,22 +35,22 @@ public class JSONNullTest { @Test public void setNullTest(){ // 忽略null - String json1 = JSONUtil.createObj().set("key1", null).toString(); + String json1 = JSONUtil.ofObj().set("key1", null).toString(); Assert.assertEquals("{}", json1); // 不忽略null - json1 = JSONUtil.createObj(JSONConfig.of().setIgnoreNullValue(false)).set("key1", null).toString(); + json1 = JSONUtil.ofObj(JSONConfig.of().setIgnoreNullValue(false)).set("key1", null).toString(); Assert.assertEquals("{\"key1\":null}", json1); } @Test public void setNullOfJSONArrayTest(){ // 忽略null - String json1 = JSONUtil.createArray().set(null).toString(); + String json1 = JSONUtil.ofArray().set(null).toString(); Assert.assertEquals("[]", json1); // 不忽略null - json1 = JSONUtil.createArray(JSONConfig.of().setIgnoreNullValue(false)).set(null).toString(); + json1 = JSONUtil.ofArray(JSONConfig.of().setIgnoreNullValue(false)).set(null).toString(); Assert.assertEquals("[null]", json1); } } diff --git a/hutool-json/src/test/java/cn/hutool/json/JSONObjectTest.java b/hutool-json/src/test/java/cn/hutool/json/JSONObjectTest.java index 1c4bf3c17..e388e7b3f 100755 --- a/hutool-json/src/test/java/cn/hutool/json/JSONObjectTest.java +++ b/hutool-json/src/test/java/cn/hutool/json/JSONObjectTest.java @@ -66,7 +66,7 @@ public class JSONObjectTest { */ @Test public void toStringTest3() { - final JSONObject json = Objects.requireNonNull(JSONUtil.createObj()// + final JSONObject json = Objects.requireNonNull(JSONUtil.ofObj()// .set("dateTime", DateUtil.parse("2019-05-02 22:12:01")))// .setDateFormat(DatePattern.NORM_DATE_PATTERN); Assert.assertEquals("{\"dateTime\":\"2019-05-02\"}", json.toString()); @@ -74,24 +74,24 @@ public class JSONObjectTest { @Test public void toStringWithDateTest() { - JSONObject json = JSONUtil.createObj().set("date", DateUtil.parse("2019-05-08 19:18:21")); + JSONObject json = JSONUtil.ofObj().set("date", DateUtil.parse("2019-05-08 19:18:21")); assert json != null; Assert.assertEquals("{\"date\":1557314301000}", json.toString()); - json = Objects.requireNonNull(JSONUtil.createObj().set("date", DateUtil.parse("2019-05-08 19:18:21"))).setDateFormat(DatePattern.NORM_DATE_PATTERN); + json = Objects.requireNonNull(JSONUtil.ofObj().set("date", DateUtil.parse("2019-05-08 19:18:21"))).setDateFormat(DatePattern.NORM_DATE_PATTERN); Assert.assertEquals("{\"date\":\"2019-05-08\"}", json.toString()); } @Test public void putAllTest() { - final JSONObject json1 = JSONUtil.createObj() + final JSONObject json1 = JSONUtil.ofObj() .set("a", "value1") .set("b", "value2") .set("c", "value3") .set("d", true); - final JSONObject json2 = JSONUtil.createObj() + final JSONObject json2 = JSONUtil.ofObj() .set("a", "value21") .set("b", "value22"); @@ -185,12 +185,12 @@ public class JSONObjectTest { @Test public void toBeanTest() { - final JSONObject subJson = JSONUtil.createObj().set("value1", "strValue1").set("value2", "234"); - final JSONObject json = JSONUtil.createObj(JSONConfig.of().setIgnoreError(true)).set("strValue", "strTest").set("intValue", 123) + final JSONObject subJson = JSONUtil.ofObj().set("value1", "strValue1").set("value2", "234"); + final JSONObject json = JSONUtil.ofObj(JSONConfig.of().setIgnoreError(true)).set("strValue", "strTest").set("intValue", 123) // 测试空字符串转对象 .set("doubleValue", "") .set("beanValue", subJson) - .set("list", JSONUtil.createArray().set("a").set("b")).set("testEnum", "TYPE_A"); + .set("list", JSONUtil.ofArray().set("a").set("b")).set("testEnum", "TYPE_A"); final TestBean bean = json.toBean(TestBean.class); Assert.assertEquals("a", bean.getList().get(0)); @@ -205,12 +205,12 @@ public class JSONObjectTest { @Test public void toBeanNullStrTest() { - final JSONObject json = JSONUtil.createObj(JSONConfig.of().setIgnoreError(true))// + final JSONObject json = JSONUtil.ofObj(JSONConfig.of().setIgnoreError(true))// .set("strValue", "null")// .set("intValue", 123)// // 子对象对应"null"字符串,如果忽略错误,跳过,否则抛出转换异常 .set("beanValue", "null")// - .set("list", JSONUtil.createArray().set("a").set("b")); + .set("list", JSONUtil.ofArray().set("a").set("b")); final TestBean bean = json.toBean(TestBean.class); // 当JSON中为字符串"null"时应被当作字符串处理 @@ -272,10 +272,10 @@ public class JSONObjectTest { */ @Test public void toBeanTest6() { - final JSONObject json = JSONUtil.createObj() + final JSONObject json = JSONUtil.ofObj() .set("targetUrl", "http://test.com") .set("success", "true") - .set("result", JSONUtil.createObj() + .set("result", JSONUtil.ofObj() .set("token", "tokenTest") .set("userId", "测试用户1")); @@ -334,7 +334,7 @@ public class JSONObjectTest { @Test public void parseBeanTest3() { - final JSONObject json = JSONUtil.createObj() + final JSONObject json = JSONUtil.ofObj() .set("code", 22) .set("data", "{\"jobId\": \"abc\", \"videoUrl\": \"http://a.com/a.mp4\"}"); @@ -375,7 +375,7 @@ public class JSONObjectTest { @Test public void beanTransTest3() { - final JSONObject userAJson = JSONUtil.createObj() + final JSONObject userAJson = JSONUtil.ofObj() .set("a", "AValue") .set("name", "nameValue") .set("date", "08:00:00"); @@ -430,7 +430,7 @@ public class JSONObjectTest { Assert.assertEquals("张三", jsonObject.getStr("name")); Assert.assertEquals(new Integer(35), jsonObject.getInt("age")); - final JSONObject json = JSONUtil.createObj() + final JSONObject json = JSONUtil.ofObj() .set("name", "张三") .set("age", 35); final BeanWithAlias bean = JSONUtil.toBean(Objects.requireNonNull(json).toString(), BeanWithAlias.class); @@ -509,7 +509,7 @@ public class JSONObjectTest { @Test public void getTimestampTest() { final String timeStr = "1970-01-01 00:00:00"; - final JSONObject jsonObject = JSONUtil.createObj().set("time", timeStr); + final JSONObject jsonObject = JSONUtil.ofObj().set("time", timeStr); final Timestamp time = jsonObject.get("time", Timestamp.class); Assert.assertEquals("1970-01-01 00:00:00.0", time.toString()); } @@ -616,7 +616,7 @@ public class JSONObjectTest { @Test public void appendTest() { - final JSONObject jsonObject = JSONUtil.createObj().append("key1", "value1"); + final JSONObject jsonObject = JSONUtil.ofObj().append("key1", "value1"); Assert.assertEquals("{\"key1\":\"value1\"}", jsonObject.toString()); jsonObject.append("key1", "value2"); @@ -649,7 +649,7 @@ public class JSONObjectTest { @Test public void filterIncludeTest() { - final JSONObject json1 = JSONUtil.createObj(JSONConfig.of()) + final JSONObject json1 = JSONUtil.ofObj(JSONConfig.of()) .set("a", "value1") .set("b", "value2") .set("c", "value3") @@ -661,7 +661,7 @@ public class JSONObjectTest { @Test public void filterExcludeTest() { - final JSONObject json1 = JSONUtil.createObj(JSONConfig.of()) + final JSONObject json1 = JSONUtil.ofObj(JSONConfig.of()) .set("a", "value1") .set("b", "value2") .set("c", "value3") @@ -673,7 +673,7 @@ public class JSONObjectTest { @Test public void editTest() { - final JSONObject json1 = JSONUtil.createObj(JSONConfig.of()) + final JSONObject json1 = JSONUtil.ofObj(JSONConfig.of()) .set("a", "value1") .set("b", "value2") .set("c", "value3") @@ -693,7 +693,7 @@ public class JSONObjectTest { @Test public void toUnderLineCaseTest() { - final JSONObject json1 = JSONUtil.createObj(JSONConfig.of()) + final JSONObject json1 = JSONUtil.ofObj(JSONConfig.of()) .set("aKey", "value1") .set("bJob", "value2") .set("cGood", "value3") @@ -708,7 +708,7 @@ public class JSONObjectTest { @Test public void nullToEmptyTest() { - final JSONObject json1 = JSONUtil.createObj(JSONConfig.of().setIgnoreNullValue(false)) + final JSONObject json1 = JSONUtil.ofObj(JSONConfig.of().setIgnoreNullValue(false)) .set("a", null) .set("b", "value2"); diff --git a/hutool-json/src/test/java/cn/hutool/json/JSONUtilTest.java b/hutool-json/src/test/java/cn/hutool/json/JSONUtilTest.java index 16525c648..04d70e4bb 100644 --- a/hutool-json/src/test/java/cn/hutool/json/JSONUtilTest.java +++ b/hutool-json/src/test/java/cn/hutool/json/JSONUtilTest.java @@ -177,7 +177,7 @@ public class JSONUtilTest { @Test public void customValueTest() { - final JSONObject jsonObject = JSONUtil.createObj() + final JSONObject jsonObject = JSONUtil.ofObj() .set("test2", (JSONString) () -> NumberUtil.format("#.0", 12.00D)); Assert.assertEquals("{\"test2\":12.0}", jsonObject.toString()); @@ -186,12 +186,12 @@ public class JSONUtilTest { @Test public void setStripTrailingZerosTest() { // 默认去除多余的0 - final JSONObject jsonObjectDefault = JSONUtil.createObj() + final JSONObject jsonObjectDefault = JSONUtil.ofObj() .set("test2", 12.00D); Assert.assertEquals("{\"test2\":12}", jsonObjectDefault.toString()); // 不去除多余的0 - final JSONObject jsonObject = JSONUtil.createObj(JSONConfig.of().setStripTrailingZeros(false)) + final JSONObject jsonObject = JSONUtil.ofObj(JSONConfig.of().setStripTrailingZeros(false)) .set("test2", 12.00D); Assert.assertEquals("{\"test2\":12.0}", jsonObject.toString()); @@ -214,7 +214,7 @@ public class JSONUtilTest { public void sqlExceptionTest(){ //https://github.com/dromara/hutool/issues/1399 // SQLException实现了Iterable接口,默认是遍历之,会栈溢出,修正后只返回string - final JSONObject set = JSONUtil.createObj().set("test", new SQLException("test")); + final JSONObject set = JSONUtil.ofObj().set("test", new SQLException("test")); Assert.assertEquals("{\"test\":\"java.sql.SQLException: test\"}", set.toString()); } @@ -227,7 +227,7 @@ public class JSONUtilTest { @Test public void toXmlTest(){ - final JSONObject obj = JSONUtil.createObj(); + final JSONObject obj = JSONUtil.ofObj(); obj.set("key1", "v1") .set("key2", ListUtil.view("a", "b", "c")); final String xmlStr = JSONUtil.toXmlStr(obj); diff --git a/hutool-json/src/test/java/cn/hutool/json/xml/XMLTest.java b/hutool-json/src/test/java/cn/hutool/json/xml/XMLTest.java index 854f76c7d..6fcc29bf0 100644 --- a/hutool-json/src/test/java/cn/hutool/json/xml/XMLTest.java +++ b/hutool-json/src/test/java/cn/hutool/json/xml/XMLTest.java @@ -11,7 +11,7 @@ public class XMLTest { @Test public void toXmlTest(){ - final JSONObject put = JSONUtil.createObj() + final JSONObject put = JSONUtil.ofObj() .set("aaa", "你好") .set("键2", "test"); final String s = JSONUtil.toXmlStr(put); @@ -31,7 +31,7 @@ public class XMLTest { @Test public void xmlContentTest(){ - final JSONObject jsonObject = JSONUtil.createObj().set("content","123456"); + final JSONObject jsonObject = JSONUtil.ofObj().set("content","123456"); String xml = JSONXMLUtil.toXml(jsonObject); Assert.assertEquals("123456", xml);