diff --git a/CHANGELOG.md b/CHANGELOG.md index d948c93d7..0ba4f03dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ * 【core 】 优化TextSimilarity.longestCommonSubstring性能(issue#I42A6V@Gitee) * 【core 】 MultipartRequestInputStream改为使用long以支持大文件(issue#I428AN@Gitee) * 【core 】 RobotUtl增加getDelay、getRobot方法(pr#1725@Github) +* 【json 】 JSON输出支持ignoreNull(issue#1728@Github) ### 🐞Bug修复 * 【core 】 修复RobotUtil双击右键问题(pr#1721@Github) 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 07d81bb33..499558873 100644 --- a/hutool-json/src/main/java/cn/hutool/json/JSONObject.java +++ b/hutool-json/src/main/java/cn/hutool/json/JSONObject.java @@ -556,7 +556,7 @@ public class JSONObject implements JSON, JSONGetter, Map public Writer write(Writer writer, int indentFactor, int indent) throws JSONException { final JSONWriter jsonWriter = JSONWriter.of(writer, indentFactor, indent, config) .beginObj(); - this.forEach((key, value)-> jsonWriter.writeKey(key).writeValue(value)); + this.forEach(jsonWriter::writeField); jsonWriter.end(); return writer; 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 e00e8ee48..f08548ee5 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 @@ -142,23 +142,33 @@ public class JSONWriter extends Writer { } /** - * 写出值,自动处理分隔符和缩进,自动判断类型,并根据不同类型写出特定格式的值 + * 写出值,自动处理分隔符和缩进,自动判断类型,并根据不同类型写出特定格式的值
+ * 如果写出的值为{@code null}或者{@link JSONNull},且配置忽略null,则跳过。 * * @param value 值 * @return this */ public JSONWriter writeValue(Object value) { - if (arrayMode) { - if (needSeparator) { - writeRaw(CharUtil.COMMA); - } - // 换行缩进 - writeLF().writeSpace(indentFactor + indent); - } else { - writeRaw(CharUtil.COLON).writeSpace(1); + if(JSONUtil.isNull(value) && config.isIgnoreNullValue()){ + return this; } - needSeparator = true; - return writeObjValue(value); + return writeValueDirect(value); + } + + /** + * 写出字段名及字段值,如果字段值是{@code null}且忽略null值,则不写出任何内容 + * + * @param key 字段名 + * @param value 字段值 + * @return this + * @since 5.7.6 + */ + public JSONWriter writeField(String key, Object value){ + if(JSONUtil.isNull(value) && config.isIgnoreNullValue()){ + return this; + } + + return writeKey(key).writeValueDirect(value); } @Override @@ -181,6 +191,25 @@ public class JSONWriter extends Writer { } // ------------------------------------------------------------------------------ Private methods + /** + * 写出值,自动处理分隔符和缩进,自动判断类型,并根据不同类型写出特定格式的值 + * + * @param value 值 + * @return this + */ + private JSONWriter writeValueDirect(Object value) { + if (arrayMode) { + if (needSeparator) { + writeRaw(CharUtil.COMMA); + } + // 换行缩进 + writeLF().writeSpace(indentFactor + indent); + } else { + writeRaw(CharUtil.COLON).writeSpace(1); + } + needSeparator = true; + return writeObjValue(value); + } /** * 写出JSON的值,根据值类型不同,输出不同内容 diff --git a/hutool-json/src/test/java/cn/hutool/json/JSONNullTest.java b/hutool-json/src/test/java/cn/hutool/json/JSONNullTest.java new file mode 100644 index 000000000..354b2afa3 --- /dev/null +++ b/hutool-json/src/test/java/cn/hutool/json/JSONNullTest.java @@ -0,0 +1,34 @@ +package cn.hutool.json; + +import org.junit.Assert; +import org.junit.Test; + +public class JSONNullTest { + + @Test + public void parseNullTest(){ + JSONObject bodyjson = JSONUtil.parseObj("{\n" + + " \"device_model\": null,\n" + + " \"device_status_date\": null,\n" + + " \"imsi\": null,\n" + + " \"act_date\": \"2021-07-23T06:23:26.000+00:00\"}"); + Assert.assertEquals(JSONNull.class, bodyjson.get("device_model").getClass()); + Assert.assertEquals(JSONNull.class, bodyjson.get("device_status_date").getClass()); + Assert.assertEquals(JSONNull.class, bodyjson.get("imsi").getClass()); + + bodyjson.getConfig().setIgnoreNullValue(true); + Assert.assertEquals("{\"act_date\":\"2021-07-23T06:23:26.000+00:00\"}", bodyjson.toString()); + } + + @Test + public void parseNullTest2(){ + JSONObject bodyjson = JSONUtil.parseObj("{\n" + + " \"device_model\": null,\n" + + " \"device_status_date\": null,\n" + + " \"imsi\": null,\n" + + " \"act_date\": \"2021-07-23T06:23:26.000+00:00\"}", true, true); + Assert.assertFalse(bodyjson.containsKey("device_model")); + Assert.assertFalse(bodyjson.containsKey("device_status_date")); + Assert.assertFalse(bodyjson.containsKey("imsi")); + } +}