mirror of
https://gitee.com/dromara/hutool.git
synced 2025-04-05 17:37:59 +08:00
fix bug
This commit is contained in:
parent
c5911c0501
commit
305737939e
@ -5,6 +5,9 @@
|
||||
|
||||
# 5.8.6.M1 (2022-08-30)
|
||||
|
||||
### ❌不兼容特性
|
||||
* 【json 】 由于设计缺陷,导致JSONObject#write方法中Filter中key的泛型不得已变动为Object,以解决无法递归的bug(issue#I5OMSC@Gitee)
|
||||
|
||||
### 🐣新特性
|
||||
* 【core 】 CollUtil新增addIfAbsent方法(pr#750@Gitee)
|
||||
* 【core 】 DateUtil.parseUTC支持只有时分的格式(issue#I5M6DP@Gitee)
|
||||
@ -29,6 +32,7 @@
|
||||
* 【core 】 修复UrlBuilder.addPath 方法传入非有效路径字符串时,会出现空指针异常的问题(issue#I5O4ML@Gitee)
|
||||
* 【core 】 修复FilterIter当参数filter为空时存在问题(issue#I5OG7U@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字符串
|
||||
* @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();
|
||||
synchronized (sw.getBuffer()) {
|
||||
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相关异常
|
||||
* @since 5.7.15
|
||||
*/
|
||||
public Writer write(Writer writer, int indentFactor, int indent, Filter<MutablePair<Integer, Object>> filter) throws JSONException {
|
||||
final JSONWriter jsonWriter = JSONWriter.of(writer, indentFactor, indent, config)
|
||||
.beginArray();
|
||||
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).beginArray();
|
||||
|
||||
CollUtil.forEach(this, (value, index) -> {
|
||||
final MutablePair<Integer, Object> pair = new MutablePair<>(index, value);
|
||||
if (null == filter || filter.accept(pair)) {
|
||||
jsonWriter.writeValue(pair.getValue());
|
||||
}
|
||||
});
|
||||
CollUtil.forEach(this, (value, index) -> jsonWriter.writeField(new MutablePair<>(index, value), filter));
|
||||
jsonWriter.end();
|
||||
// 此处不关闭Writer,考虑writer后续还需要填内容
|
||||
return writer;
|
||||
|
@ -541,7 +541,7 @@ public class JSONObject extends MapWrapper<String, Object> implements JSON, JSON
|
||||
* @return JSON字符串
|
||||
* @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();
|
||||
synchronized (sw.getBuffer()) {
|
||||
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相关异常
|
||||
* @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)
|
||||
.beginObj();
|
||||
this.forEach((key, value) -> {
|
||||
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);
|
||||
}
|
||||
});
|
||||
this.forEach((key, value) -> jsonWriter.writeField(new MutablePair<>(key, value), filter));
|
||||
jsonWriter.end();
|
||||
// 此处不关闭Writer,考虑writer后续还需要填内容
|
||||
return writer;
|
||||
|
@ -5,6 +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.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.CharUtil;
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
@ -152,7 +154,7 @@ public class JSONWriter extends Writer {
|
||||
if(JSONUtil.isNull(value) && config.isIgnoreNullValue()){
|
||||
return this;
|
||||
}
|
||||
return writeValueDirect(value);
|
||||
return writeValueDirect(value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -162,12 +164,37 @@ public class JSONWriter extends Writer {
|
||||
* @param value 字段值
|
||||
* @return this
|
||||
* @since 5.7.6
|
||||
* @deprecated 请使用 {@link #writeField(MutablePair, Filter)}
|
||||
*/
|
||||
@Deprecated
|
||||
public JSONWriter writeField(String key, Object value){
|
||||
if(JSONUtil.isNull(value) && config.isIgnoreNullValue()){
|
||||
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
|
||||
@ -194,9 +221,10 @@ public class JSONWriter extends Writer {
|
||||
* 写出值,自动处理分隔符和缩进,自动判断类型,并根据不同类型写出特定格式的值
|
||||
*
|
||||
* @param value 值
|
||||
* @param filter 键值对过滤器
|
||||
* @return this
|
||||
*/
|
||||
private JSONWriter writeValueDirect(Object value) {
|
||||
private JSONWriter writeValueDirect(Object value, Filter<MutablePair<Object, Object>> filter) {
|
||||
if (arrayMode) {
|
||||
if (needSeparator) {
|
||||
writeRaw(CharUtil.COMMA);
|
||||
@ -207,21 +235,26 @@ public class JSONWriter extends Writer {
|
||||
writeRaw(CharUtil.COLON).writeSpace(1);
|
||||
}
|
||||
needSeparator = true;
|
||||
return writeObjValue(value);
|
||||
return writeObjValue(value, filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* 写出JSON的值,根据值类型不同,输出不同内容
|
||||
*
|
||||
* @param value 值
|
||||
* @param filter 过滤器
|
||||
* @return this
|
||||
*/
|
||||
private JSONWriter writeObjValue(Object value) {
|
||||
private JSONWriter writeObjValue(Object value, Filter<MutablePair<Object, Object>> filter) {
|
||||
final int indent = indentFactor + this.indent;
|
||||
if (value == null || value instanceof JSONNull) {
|
||||
writeRaw(JSONNull.NULL.toString());
|
||||
} 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) {
|
||||
new JSONObject(value).write(writer, indentFactor, indent);
|
||||
} 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);
|
||||
|
||||
final String s = json1.toJSONString(0, (pair) -> {
|
||||
pair.setKey(StrUtil.toUnderlineCase(pair.getKey()));
|
||||
pair.setKey(StrUtil.toUnderlineCase(pair.getKey().toString()));
|
||||
return true;
|
||||
});
|
||||
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…
Reference in New Issue
Block a user