mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
fix bug
This commit is contained in:
parent
c5911c0501
commit
305737939e
@ -5,6 +5,9 @@
|
|||||||
|
|
||||||
# 5.8.6.M1 (2022-08-30)
|
# 5.8.6.M1 (2022-08-30)
|
||||||
|
|
||||||
|
### ❌不兼容特性
|
||||||
|
* 【json 】 由于设计缺陷,导致JSONObject#write方法中Filter中key的泛型不得已变动为Object,以解决无法递归的bug(issue#I5OMSC@Gitee)
|
||||||
|
|
||||||
### 🐣新特性
|
### 🐣新特性
|
||||||
* 【core 】 CollUtil新增addIfAbsent方法(pr#750@Gitee)
|
* 【core 】 CollUtil新增addIfAbsent方法(pr#750@Gitee)
|
||||||
* 【core 】 DateUtil.parseUTC支持只有时分的格式(issue#I5M6DP@Gitee)
|
* 【core 】 DateUtil.parseUTC支持只有时分的格式(issue#I5M6DP@Gitee)
|
||||||
@ -29,6 +32,7 @@
|
|||||||
* 【core 】 修复UrlBuilder.addPath 方法传入非有效路径字符串时,会出现空指针异常的问题(issue#I5O4ML@Gitee)
|
* 【core 】 修复UrlBuilder.addPath 方法传入非有效路径字符串时,会出现空指针异常的问题(issue#I5O4ML@Gitee)
|
||||||
* 【core 】 修复FilterIter当参数filter为空时存在问题(issue#I5OG7U@Gitee)
|
* 【core 】 修复FilterIter当参数filter为空时存在问题(issue#I5OG7U@Gitee)
|
||||||
* 【poi 】 修复Excel读取提示信息错误(issue#I5OSFC@Gitee)
|
* 【poi 】 修复Excel读取提示信息错误(issue#I5OSFC@Gitee)
|
||||||
|
* 【json 】 解决JSONObject#write无法递归的bug(issue#I5OMSC@Gitee)
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -537,7 +537,7 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
|
|||||||
* @return JSON字符串
|
* @return JSON字符串
|
||||||
* @since 5.7.15
|
* @since 5.7.15
|
||||||
*/
|
*/
|
||||||
public String toJSONString(int indentFactor, Filter<MutablePair<Integer, Object>> filter) {
|
public String toJSONString(int indentFactor, Filter<MutablePair<Object, Object>> filter) {
|
||||||
final StringWriter sw = new StringWriter();
|
final StringWriter sw = new StringWriter();
|
||||||
synchronized (sw.getBuffer()) {
|
synchronized (sw.getBuffer()) {
|
||||||
return this.write(sw, indentFactor, 0, filter).toString();
|
return this.write(sw, indentFactor, 0, filter).toString();
|
||||||
@ -561,16 +561,10 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
|
|||||||
* @throws JSONException JSON相关异常
|
* @throws JSONException JSON相关异常
|
||||||
* @since 5.7.15
|
* @since 5.7.15
|
||||||
*/
|
*/
|
||||||
public Writer write(Writer writer, int indentFactor, int indent, Filter<MutablePair<Integer, Object>> filter) throws JSONException {
|
public Writer write(Writer writer, int indentFactor, int indent, Filter<MutablePair<Object, Object>> filter) throws JSONException {
|
||||||
final JSONWriter jsonWriter = JSONWriter.of(writer, indentFactor, indent, config)
|
final JSONWriter jsonWriter = JSONWriter.of(writer, indentFactor, indent, config).beginArray();
|
||||||
.beginArray();
|
|
||||||
|
|
||||||
CollUtil.forEach(this, (value, index) -> {
|
CollUtil.forEach(this, (value, index) -> jsonWriter.writeField(new MutablePair<>(index, value), filter));
|
||||||
final MutablePair<Integer, Object> pair = new MutablePair<>(index, value);
|
|
||||||
if (null == filter || filter.accept(pair)) {
|
|
||||||
jsonWriter.writeValue(pair.getValue());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
jsonWriter.end();
|
jsonWriter.end();
|
||||||
// 此处不关闭Writer,考虑writer后续还需要填内容
|
// 此处不关闭Writer,考虑writer后续还需要填内容
|
||||||
return writer;
|
return writer;
|
||||||
|
@ -541,7 +541,7 @@ public class JSONObject extends MapWrapper<String, Object> implements JSON, JSON
|
|||||||
* @return JSON字符串
|
* @return JSON字符串
|
||||||
* @since 5.7.15
|
* @since 5.7.15
|
||||||
*/
|
*/
|
||||||
public String toJSONString(int indentFactor, Filter<MutablePair<String, Object>> filter) {
|
public String toJSONString(int indentFactor, Filter<MutablePair<Object, Object>> filter) {
|
||||||
final StringWriter sw = new StringWriter();
|
final StringWriter sw = new StringWriter();
|
||||||
synchronized (sw.getBuffer()) {
|
synchronized (sw.getBuffer()) {
|
||||||
return this.write(sw, indentFactor, 0, filter).toString();
|
return this.write(sw, indentFactor, 0, filter).toString();
|
||||||
@ -565,20 +565,10 @@ public class JSONObject extends MapWrapper<String, Object> implements JSON, JSON
|
|||||||
* @throws JSONException JSON相关异常
|
* @throws JSONException JSON相关异常
|
||||||
* @since 5.7.15
|
* @since 5.7.15
|
||||||
*/
|
*/
|
||||||
public Writer write(Writer writer, int indentFactor, int indent, Filter<MutablePair<String, Object>> filter) throws JSONException {
|
public Writer write(Writer writer, int indentFactor, int indent, Filter<MutablePair<Object, Object>> filter) throws JSONException {
|
||||||
final JSONWriter jsonWriter = JSONWriter.of(writer, indentFactor, indent, config)
|
final JSONWriter jsonWriter = JSONWriter.of(writer, indentFactor, indent, config)
|
||||||
.beginObj();
|
.beginObj();
|
||||||
this.forEach((key, value) -> {
|
this.forEach((key, value) -> jsonWriter.writeField(new MutablePair<>(key, value), filter));
|
||||||
if (null != filter) {
|
|
||||||
final MutablePair<String, Object> pair = new MutablePair<>(key, value);
|
|
||||||
if (filter.accept(pair)) {
|
|
||||||
// 使用修改后的键值对
|
|
||||||
jsonWriter.writeField(pair.getKey(), pair.getValue());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
jsonWriter.writeField(key, value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
jsonWriter.end();
|
jsonWriter.end();
|
||||||
// 此处不关闭Writer,考虑writer后续还需要填内容
|
// 此处不关闭Writer,考虑writer后续还需要填内容
|
||||||
return writer;
|
return writer;
|
||||||
|
@ -5,6 +5,8 @@ import cn.hutool.core.date.DateUtil;
|
|||||||
import cn.hutool.core.date.TemporalAccessorUtil;
|
import cn.hutool.core.date.TemporalAccessorUtil;
|
||||||
import cn.hutool.core.date.format.GlobalCustomFormat;
|
import cn.hutool.core.date.format.GlobalCustomFormat;
|
||||||
import cn.hutool.core.io.IORuntimeException;
|
import cn.hutool.core.io.IORuntimeException;
|
||||||
|
import cn.hutool.core.lang.Filter;
|
||||||
|
import cn.hutool.core.lang.mutable.MutablePair;
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
import cn.hutool.core.util.ArrayUtil;
|
||||||
import cn.hutool.core.util.CharUtil;
|
import cn.hutool.core.util.CharUtil;
|
||||||
import cn.hutool.core.util.NumberUtil;
|
import cn.hutool.core.util.NumberUtil;
|
||||||
@ -152,7 +154,7 @@ public class JSONWriter extends Writer {
|
|||||||
if(JSONUtil.isNull(value) && config.isIgnoreNullValue()){
|
if(JSONUtil.isNull(value) && config.isIgnoreNullValue()){
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
return writeValueDirect(value);
|
return writeValueDirect(value, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -162,12 +164,37 @@ public class JSONWriter extends Writer {
|
|||||||
* @param value 字段值
|
* @param value 字段值
|
||||||
* @return this
|
* @return this
|
||||||
* @since 5.7.6
|
* @since 5.7.6
|
||||||
|
* @deprecated 请使用 {@link #writeField(MutablePair, Filter)}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public JSONWriter writeField(String key, Object value){
|
public JSONWriter writeField(String key, Object value){
|
||||||
if(JSONUtil.isNull(value) && config.isIgnoreNullValue()){
|
if(JSONUtil.isNull(value) && config.isIgnoreNullValue()){
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
return writeKey(key).writeValueDirect(value);
|
return writeKey(key).writeValueDirect(value, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 写出字段名及字段值,如果字段值是{@code null}且忽略null值,则不写出任何内容
|
||||||
|
*
|
||||||
|
* @param pair 键值对
|
||||||
|
* @param filter 键值对的过滤器,可以编辑键值对
|
||||||
|
* @return this
|
||||||
|
* @since 5.8.6
|
||||||
|
*/
|
||||||
|
public JSONWriter writeField(MutablePair<Object, Object> pair, Filter<MutablePair<Object, Object>> filter){
|
||||||
|
if(JSONUtil.isNull(pair.getValue()) && config.isIgnoreNullValue()){
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null == filter || filter.accept(pair)) {
|
||||||
|
if(false == arrayMode){
|
||||||
|
// JSONArray只写值,JSONObject写键值对
|
||||||
|
writeKey(StrUtil.toString(pair.getKey()));
|
||||||
|
}
|
||||||
|
return writeValueDirect(pair.getValue(), filter);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -194,9 +221,10 @@ public class JSONWriter extends Writer {
|
|||||||
* 写出值,自动处理分隔符和缩进,自动判断类型,并根据不同类型写出特定格式的值
|
* 写出值,自动处理分隔符和缩进,自动判断类型,并根据不同类型写出特定格式的值
|
||||||
*
|
*
|
||||||
* @param value 值
|
* @param value 值
|
||||||
|
* @param filter 键值对过滤器
|
||||||
* @return this
|
* @return this
|
||||||
*/
|
*/
|
||||||
private JSONWriter writeValueDirect(Object value) {
|
private JSONWriter writeValueDirect(Object value, Filter<MutablePair<Object, Object>> filter) {
|
||||||
if (arrayMode) {
|
if (arrayMode) {
|
||||||
if (needSeparator) {
|
if (needSeparator) {
|
||||||
writeRaw(CharUtil.COMMA);
|
writeRaw(CharUtil.COMMA);
|
||||||
@ -207,21 +235,26 @@ public class JSONWriter extends Writer {
|
|||||||
writeRaw(CharUtil.COLON).writeSpace(1);
|
writeRaw(CharUtil.COLON).writeSpace(1);
|
||||||
}
|
}
|
||||||
needSeparator = true;
|
needSeparator = true;
|
||||||
return writeObjValue(value);
|
return writeObjValue(value, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 写出JSON的值,根据值类型不同,输出不同内容
|
* 写出JSON的值,根据值类型不同,输出不同内容
|
||||||
*
|
*
|
||||||
* @param value 值
|
* @param value 值
|
||||||
|
* @param filter 过滤器
|
||||||
* @return this
|
* @return this
|
||||||
*/
|
*/
|
||||||
private JSONWriter writeObjValue(Object value) {
|
private JSONWriter writeObjValue(Object value, Filter<MutablePair<Object, Object>> filter) {
|
||||||
final int indent = indentFactor + this.indent;
|
final int indent = indentFactor + this.indent;
|
||||||
if (value == null || value instanceof JSONNull) {
|
if (value == null || value instanceof JSONNull) {
|
||||||
writeRaw(JSONNull.NULL.toString());
|
writeRaw(JSONNull.NULL.toString());
|
||||||
} else if (value instanceof JSON) {
|
} else if (value instanceof JSON) {
|
||||||
((JSON) value).write(writer, indentFactor, indent);
|
if(value instanceof JSONObject){
|
||||||
|
((JSONObject) value).write(writer, indentFactor, indent, filter);
|
||||||
|
}else if(value instanceof JSONArray){
|
||||||
|
((JSONArray) value).write(writer, indentFactor, indent, filter);
|
||||||
|
}
|
||||||
} else if (value instanceof Map || value instanceof Map.Entry) {
|
} else if (value instanceof Map || value instanceof Map.Entry) {
|
||||||
new JSONObject(value).write(writer, indentFactor, indent);
|
new JSONObject(value).write(writer, indentFactor, indent);
|
||||||
} else if (value instanceof Iterable || value instanceof Iterator || ArrayUtil.isArray(value)) {
|
} else if (value instanceof Iterable || value instanceof Iterator || ArrayUtil.isArray(value)) {
|
||||||
|
26
hutool-json/src/test/java/cn/hutool/json/IssueI5OMSCTest.java
Executable file
26
hutool-json/src/test/java/cn/hutool/json/IssueI5OMSCTest.java
Executable file
@ -0,0 +1,26 @@
|
|||||||
|
package cn.hutool.json;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.ListUtil;
|
||||||
|
import cn.hutool.core.io.resource.ResourceUtil;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Predicate多层过滤
|
||||||
|
*/
|
||||||
|
public class IssueI5OMSCTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void filterTest(){
|
||||||
|
final JSONObject json = JSONUtil.parseObj(ResourceUtil.readUtf8Str("issueI5OMSC.json"));
|
||||||
|
|
||||||
|
final String s = json.toJSONString(0, (entry) -> {
|
||||||
|
final Object key = entry.getKey();
|
||||||
|
if(key instanceof String){
|
||||||
|
return ListUtil.of("store", "bicycle", "color", "book", "author").contains(key);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
Assert.assertEquals("{\"store\":{\"bicycle\":{\"color\":\"red\"},\"book\":[{\"author\":\"Evelyn Waugh\"},{\"author\":\"Evelyn Waugh02\"}]}}", s);
|
||||||
|
}
|
||||||
|
}
|
@ -698,7 +698,7 @@ public class JSONObjectTest {
|
|||||||
.set("d", true);
|
.set("d", true);
|
||||||
|
|
||||||
final String s = json1.toJSONString(0, (pair) -> {
|
final String s = json1.toJSONString(0, (pair) -> {
|
||||||
pair.setKey(StrUtil.toUnderlineCase(pair.getKey()));
|
pair.setKey(StrUtil.toUnderlineCase(pair.getKey().toString()));
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
Assert.assertEquals("{\"a_key\":\"value1\",\"b_job\":\"value2\",\"c_good\":\"value3\",\"d\":true}", s);
|
Assert.assertEquals("{\"a_key\":\"value1\",\"b_job\":\"value2\",\"c_good\":\"value3\",\"d\":true}", s);
|
||||||
|
32
hutool-json/src/test/resources/issueI5OMSC.json
Executable file
32
hutool-json/src/test/resources/issueI5OMSC.json
Executable file
@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"store": {
|
||||||
|
"bicycle": {
|
||||||
|
"color": "red",
|
||||||
|
"price": 19.95
|
||||||
|
},
|
||||||
|
"book": [
|
||||||
|
{
|
||||||
|
"category": "fiction",
|
||||||
|
"author": "Evelyn Waugh",
|
||||||
|
"title": "Sword of Honour",
|
||||||
|
"price": 12.99,
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"name": "wujing001",
|
||||||
|
"age": 18
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "wujing002",
|
||||||
|
"age": 18
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category": "fiction02",
|
||||||
|
"author": "Evelyn Waugh02",
|
||||||
|
"title": "Sword of Honour02",
|
||||||
|
"price": 12.99
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user