diff --git a/CHANGELOG.md b/CHANGELOG.md index c0cfb0679..87086db3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ ### Bug修复 * 【json 】 JSONUtil.isJson方法改变trim策略,解决特殊空白符导致判断失败问题 +* 【json 】 修复SQLEXception导致的栈溢出(issue#1401@Github) ------------------------------------------------------------------------------------------------------------- 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 b5641b305..393cc0c61 100644 --- a/hutool-json/src/main/java/cn/hutool/json/JSONArray.java +++ b/hutool-json/src/main/java/cn/hutool/json/JSONArray.java @@ -26,11 +26,11 @@ import static cn.hutool.json.JSONConverter.jsonConvert; * JSON数组 * JSON数组是表示中括号括住的数据表现形式 * 对应的JSON字符串格格式例如: - * + * *
* ["a", "b", "c", 12] *
* 1. 数组 * 2. {@link Iterable}对象 @@ -154,7 +154,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando /** * 从对象构造 * 支持以下类型的参数: - * + * * * 1. 数组 * 2. {@link Iterable}对象 @@ -172,7 +172,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando /** * 从对象构造 * 支持以下类型的参数: - * + * * * 1. 数组 * 2. {@link Iterable}对象 @@ -197,7 +197,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando /** * 设置转为字符串时的日期格式,默认为时间戳(null值) - * + * * @param format 格式,null表示使用时间戳 * @return this * @since 4.1.19 @@ -343,7 +343,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando /** * 当此JSON列表的每个元素都是一个JSONObject时,可以调用此方法返回一个Iterable,便于使用foreach语法遍历 - * + * * @return Iterable * @since 4.0.12 */ @@ -493,7 +493,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando /** * 转为Bean数组 - * + * * @param arrayClass 数组元素类型 * @return 实体类对象 */ @@ -503,7 +503,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando /** * 转为{@link ArrayList} - * + * * @param 元素类型 * @param elementType 元素类型 * @return {@link ArrayList} @@ -536,7 +536,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando /** * 将JSON内容写入Writer - * + * * @param writer writer * @param indentFactor 缩进因子,定义每一级别增加的缩进量 * @param indent 本级别缩进量 @@ -575,7 +575,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando /** * 初始化 - * + * * @param source 数组或集合或JSON数组字符串 * @throws JSONException 非数组或集合 */ @@ -605,15 +605,21 @@ public class JSONArray implements JSON, JSONGetter, List, Rando } else { throw new JSONException("JSONArray initial value should be a string or collection or array."); } + + Object next; while (iter.hasNext()) { - this.add(iter.next()); + next = iter.next(); + // 检查循环引用 + if(next != source){ + this.add(next); + } } } } /** * 初始化 - * + * * @param source JSON字符串 */ private void init(CharSequence source) { @@ -624,7 +630,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando /** * 初始化 - * + * * @param x {@link JSONTokener} */ private void init(JSONTokener x) { 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 18a8d98a8..b25f910ac 100644 --- a/hutool-json/src/main/java/cn/hutool/json/JSONObject.java +++ b/hutool-json/src/main/java/cn/hutool/json/JSONObject.java @@ -24,7 +24,6 @@ import java.math.BigDecimal; import java.math.BigInteger; import java.util.Collection; import java.util.Enumeration; -import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.ResourceBundle; @@ -653,7 +652,7 @@ public class JSONObject implements JSON, JSONGetter, Map return; } - if(ArrayUtil.isArray(source) || source instanceof Iterable || source instanceof Iterator){ + if(ArrayUtil.isArray(source)){ // 不支持集合类型转换为JSONObject throw new JSONException("Unsupported type [{}] to JSONObject!", source.getClass()); } 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 238fe2321..6cccd9bf1 100644 --- a/hutool-json/src/main/java/cn/hutool/json/JSONUtil.java +++ b/hutool-json/src/main/java/cn/hutool/json/JSONUtil.java @@ -21,6 +21,7 @@ import java.io.StringWriter; import java.io.Writer; import java.lang.reflect.Type; import java.nio.charset.Charset; +import java.sql.SQLException; import java.time.temporal.TemporalAccessor; import java.util.Calendar; import java.util.Date; @@ -735,6 +736,11 @@ public final class JSONUtil { } try { + // fix issue#1401@Github + if(object instanceof SQLException){ + return object.toString(); + } + // JSONArray if (object instanceof Iterable || ArrayUtil.isArray(object)) { return new JSONArray(object, jsonConfig); 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 5348ab732..60a49d8aa 100644 --- a/hutool-json/src/test/java/cn/hutool/json/JSONUtilTest.java +++ b/hutool-json/src/test/java/cn/hutool/json/JSONUtilTest.java @@ -11,6 +11,7 @@ import cn.hutool.json.test.bean.UserC; import org.junit.Assert; import org.junit.Test; +import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; @@ -179,4 +180,12 @@ public class JSONUtilTest { " \"test\": \"\\\\地库地库\",\n" + "}"); } + + @Test + public void sqlExceptionTest(){ + //https://github.com/looly/hutool/issues/1401 + // SQLException实现了Iterable接口,默认是遍历之,会栈溢出,修正后只返回string + final JSONObject set = JSONUtil.createObj().set("test", new SQLException("test")); + Assert.assertEquals("{\"test\":\"java.sql.SQLException: test\"}", set.toString()); + } }
* 1. 数组 * 2. {@link Iterable}对象 @@ -172,7 +172,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando /** * 从对象构造 * 支持以下类型的参数: - * + * * * 1. 数组 * 2. {@link Iterable}对象 @@ -197,7 +197,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando /** * 设置转为字符串时的日期格式,默认为时间戳(null值) - * + * * @param format 格式,null表示使用时间戳 * @return this * @since 4.1.19 @@ -343,7 +343,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando /** * 当此JSON列表的每个元素都是一个JSONObject时,可以调用此方法返回一个Iterable,便于使用foreach语法遍历 - * + * * @return Iterable * @since 4.0.12 */ @@ -493,7 +493,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando /** * 转为Bean数组 - * + * * @param arrayClass 数组元素类型 * @return 实体类对象 */ @@ -503,7 +503,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando /** * 转为{@link ArrayList} - * + * * @param 元素类型 * @param elementType 元素类型 * @return {@link ArrayList} @@ -536,7 +536,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando /** * 将JSON内容写入Writer - * + * * @param writer writer * @param indentFactor 缩进因子,定义每一级别增加的缩进量 * @param indent 本级别缩进量 @@ -575,7 +575,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando /** * 初始化 - * + * * @param source 数组或集合或JSON数组字符串 * @throws JSONException 非数组或集合 */ @@ -605,15 +605,21 @@ public class JSONArray implements JSON, JSONGetter, List, Rando } else { throw new JSONException("JSONArray initial value should be a string or collection or array."); } + + Object next; while (iter.hasNext()) { - this.add(iter.next()); + next = iter.next(); + // 检查循环引用 + if(next != source){ + this.add(next); + } } } } /** * 初始化 - * + * * @param source JSON字符串 */ private void init(CharSequence source) { @@ -624,7 +630,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando /** * 初始化 - * + * * @param x {@link JSONTokener} */ private void init(JSONTokener x) { 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 18a8d98a8..b25f910ac 100644 --- a/hutool-json/src/main/java/cn/hutool/json/JSONObject.java +++ b/hutool-json/src/main/java/cn/hutool/json/JSONObject.java @@ -24,7 +24,6 @@ import java.math.BigDecimal; import java.math.BigInteger; import java.util.Collection; import java.util.Enumeration; -import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.ResourceBundle; @@ -653,7 +652,7 @@ public class JSONObject implements JSON, JSONGetter, Map return; } - if(ArrayUtil.isArray(source) || source instanceof Iterable || source instanceof Iterator){ + if(ArrayUtil.isArray(source)){ // 不支持集合类型转换为JSONObject throw new JSONException("Unsupported type [{}] to JSONObject!", source.getClass()); } 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 238fe2321..6cccd9bf1 100644 --- a/hutool-json/src/main/java/cn/hutool/json/JSONUtil.java +++ b/hutool-json/src/main/java/cn/hutool/json/JSONUtil.java @@ -21,6 +21,7 @@ import java.io.StringWriter; import java.io.Writer; import java.lang.reflect.Type; import java.nio.charset.Charset; +import java.sql.SQLException; import java.time.temporal.TemporalAccessor; import java.util.Calendar; import java.util.Date; @@ -735,6 +736,11 @@ public final class JSONUtil { } try { + // fix issue#1401@Github + if(object instanceof SQLException){ + return object.toString(); + } + // JSONArray if (object instanceof Iterable || ArrayUtil.isArray(object)) { return new JSONArray(object, jsonConfig); 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 5348ab732..60a49d8aa 100644 --- a/hutool-json/src/test/java/cn/hutool/json/JSONUtilTest.java +++ b/hutool-json/src/test/java/cn/hutool/json/JSONUtilTest.java @@ -11,6 +11,7 @@ import cn.hutool.json.test.bean.UserC; import org.junit.Assert; import org.junit.Test; +import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; @@ -179,4 +180,12 @@ public class JSONUtilTest { " \"test\": \"\\\\地库地库\",\n" + "}"); } + + @Test + public void sqlExceptionTest(){ + //https://github.com/looly/hutool/issues/1401 + // SQLException实现了Iterable接口,默认是遍历之,会栈溢出,修正后只返回string + final JSONObject set = JSONUtil.createObj().set("test", new SQLException("test")); + Assert.assertEquals("{\"test\":\"java.sql.SQLException: test\"}", set.toString()); + } }
* 1. 数组 * 2. {@link Iterable}对象 @@ -197,7 +197,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando /** * 设置转为字符串时的日期格式,默认为时间戳(null值) - * + * * @param format 格式,null表示使用时间戳 * @return this * @since 4.1.19 @@ -343,7 +343,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando /** * 当此JSON列表的每个元素都是一个JSONObject时,可以调用此方法返回一个Iterable,便于使用foreach语法遍历 - * + * * @return Iterable * @since 4.0.12 */ @@ -493,7 +493,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando /** * 转为Bean数组 - * + * * @param arrayClass 数组元素类型 * @return 实体类对象 */ @@ -503,7 +503,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando /** * 转为{@link ArrayList} - * + * * @param 元素类型 * @param elementType 元素类型 * @return {@link ArrayList} @@ -536,7 +536,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando /** * 将JSON内容写入Writer - * + * * @param writer writer * @param indentFactor 缩进因子,定义每一级别增加的缩进量 * @param indent 本级别缩进量 @@ -575,7 +575,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando /** * 初始化 - * + * * @param source 数组或集合或JSON数组字符串 * @throws JSONException 非数组或集合 */ @@ -605,15 +605,21 @@ public class JSONArray implements JSON, JSONGetter, List, Rando } else { throw new JSONException("JSONArray initial value should be a string or collection or array."); } + + Object next; while (iter.hasNext()) { - this.add(iter.next()); + next = iter.next(); + // 检查循环引用 + if(next != source){ + this.add(next); + } } } } /** * 初始化 - * + * * @param source JSON字符串 */ private void init(CharSequence source) { @@ -624,7 +630,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando /** * 初始化 - * + * * @param x {@link JSONTokener} */ private void init(JSONTokener x) { 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 18a8d98a8..b25f910ac 100644 --- a/hutool-json/src/main/java/cn/hutool/json/JSONObject.java +++ b/hutool-json/src/main/java/cn/hutool/json/JSONObject.java @@ -24,7 +24,6 @@ import java.math.BigDecimal; import java.math.BigInteger; import java.util.Collection; import java.util.Enumeration; -import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.ResourceBundle; @@ -653,7 +652,7 @@ public class JSONObject implements JSON, JSONGetter, Map return; } - if(ArrayUtil.isArray(source) || source instanceof Iterable || source instanceof Iterator){ + if(ArrayUtil.isArray(source)){ // 不支持集合类型转换为JSONObject throw new JSONException("Unsupported type [{}] to JSONObject!", source.getClass()); } 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 238fe2321..6cccd9bf1 100644 --- a/hutool-json/src/main/java/cn/hutool/json/JSONUtil.java +++ b/hutool-json/src/main/java/cn/hutool/json/JSONUtil.java @@ -21,6 +21,7 @@ import java.io.StringWriter; import java.io.Writer; import java.lang.reflect.Type; import java.nio.charset.Charset; +import java.sql.SQLException; import java.time.temporal.TemporalAccessor; import java.util.Calendar; import java.util.Date; @@ -735,6 +736,11 @@ public final class JSONUtil { } try { + // fix issue#1401@Github + if(object instanceof SQLException){ + return object.toString(); + } + // JSONArray if (object instanceof Iterable || ArrayUtil.isArray(object)) { return new JSONArray(object, jsonConfig); 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 5348ab732..60a49d8aa 100644 --- a/hutool-json/src/test/java/cn/hutool/json/JSONUtilTest.java +++ b/hutool-json/src/test/java/cn/hutool/json/JSONUtilTest.java @@ -11,6 +11,7 @@ import cn.hutool.json.test.bean.UserC; import org.junit.Assert; import org.junit.Test; +import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; @@ -179,4 +180,12 @@ public class JSONUtilTest { " \"test\": \"\\\\地库地库\",\n" + "}"); } + + @Test + public void sqlExceptionTest(){ + //https://github.com/looly/hutool/issues/1401 + // SQLException实现了Iterable接口,默认是遍历之,会栈溢出,修正后只返回string + final JSONObject set = JSONUtil.createObj().set("test", new SQLException("test")); + Assert.assertEquals("{\"test\":\"java.sql.SQLException: test\"}", set.toString()); + } }