mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
remove JSONNull
This commit is contained in:
parent
f985887406
commit
c914574c30
@ -186,15 +186,13 @@ public class ObjUtil {
|
||||
*
|
||||
* <pre>
|
||||
* 1. == null
|
||||
* 2. equals(null)
|
||||
* </pre>
|
||||
*
|
||||
* @param obj 对象
|
||||
* @return 是否为null
|
||||
*/
|
||||
public static boolean isNull(final Object obj) {
|
||||
//noinspection ConstantConditions
|
||||
return null == obj || obj.equals(null);
|
||||
return null == obj;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -59,8 +59,8 @@ public final class InternalJSONUtil {
|
||||
* @throws JSONException If the value is or contains an invalid number.
|
||||
*/
|
||||
static String valueToString(final Object value) throws JSONException {
|
||||
if (value == null || value instanceof JSONNull) {
|
||||
return JSONNull.NULL.toString();
|
||||
if (value == null) {
|
||||
return StrUtil.NULL;
|
||||
}
|
||||
if (value instanceof JSONString) {
|
||||
try {
|
||||
@ -94,7 +94,7 @@ public final class InternalJSONUtil {
|
||||
public static Object stringToValue(final String string) {
|
||||
// null处理
|
||||
if (StrUtil.isEmpty(string) || StrUtil.NULL.equalsIgnoreCase(string)) {
|
||||
return JSONNull.NULL;
|
||||
return null;
|
||||
}
|
||||
|
||||
// boolean处理
|
||||
|
@ -36,7 +36,9 @@ public interface JSON extends Cloneable, Serializable {
|
||||
* @see BeanPath#get(Object)
|
||||
* @since 4.0.6
|
||||
*/
|
||||
Object getByPath(String expression);
|
||||
default Object getByPath(String expression){
|
||||
return BeanPath.of(expression).get(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置表达式指定位置(或filed对应)的值<br>
|
||||
@ -59,7 +61,9 @@ public interface JSON extends Cloneable, Serializable {
|
||||
* @param expression 表达式
|
||||
* @param value 值
|
||||
*/
|
||||
void putByPath(String expression, Object value);
|
||||
default void putByPath(String expression, Object value){
|
||||
BeanPath.of(expression).set(this, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过表达式获取JSON中嵌套的对象<br>
|
||||
|
@ -1,13 +1,12 @@
|
||||
package cn.hutool.json;
|
||||
|
||||
import cn.hutool.core.bean.BeanPath;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.convert.impl.ArrayConverter;
|
||||
import cn.hutool.core.lang.func.Filter;
|
||||
import cn.hutool.core.lang.mutable.Mutable;
|
||||
import cn.hutool.core.lang.mutable.MutableObj;
|
||||
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.serialize.JSONWriter;
|
||||
@ -192,19 +191,9 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
|
||||
return (index < 0 || index >= this.size()) ? defaultValue : this.rawList.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getByPath(final String expression) {
|
||||
return BeanPath.of(expression).get(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getByPath(final String expression, final Class<T> resultType) {
|
||||
return JSONConverter.jsonConvert(resultType, getByPath(expression), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putByPath(final String expression, final Object value) {
|
||||
BeanPath.of(expression).set(this, value);
|
||||
return JSONConverter.jsonConvert(resultType, getByPath(expression), this.config.isIgnoreError());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -376,6 +365,9 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
|
||||
}
|
||||
final ArrayList<Object> list = new ArrayList<>(c.size());
|
||||
for (final Object object : c) {
|
||||
if(null == object && config.isIgnoreNullValue()){
|
||||
continue;
|
||||
}
|
||||
list.add(JSONUtil.wrap(object, this.config));
|
||||
}
|
||||
return rawList.addAll(index, list);
|
||||
@ -428,25 +420,36 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
|
||||
}
|
||||
}
|
||||
|
||||
// 越界则追加到指定位置
|
||||
if (index >= size()) {
|
||||
add(index, element);
|
||||
return null;
|
||||
}
|
||||
if(null == element && config.isIgnoreNullValue()){
|
||||
return null;
|
||||
}
|
||||
return this.rawList.set(index, JSONUtil.wrap(element, this.config));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(final int index, final Object element) {
|
||||
if (index < 0) {
|
||||
throw new JSONException("JSONArray[{}] not found.", index);
|
||||
public void add(int index, final Object element) {
|
||||
if(null == element && config.isIgnoreNullValue()){
|
||||
return;
|
||||
}
|
||||
if (index < this.size()) {
|
||||
if (index < 0) {
|
||||
index = 0;
|
||||
}
|
||||
InternalJSONUtil.testValidity(element);
|
||||
this.rawList.add(index, JSONUtil.wrap(element, this.config));
|
||||
} else {
|
||||
while (index != this.size()) {
|
||||
this.add(JSONNull.NULL);
|
||||
if(false == config.isIgnoreNullValue()){
|
||||
while (index != this.size()) {
|
||||
// 非末尾,则填充null
|
||||
this.add(null);
|
||||
}
|
||||
}
|
||||
this.set(element);
|
||||
this.add(element);
|
||||
}
|
||||
|
||||
}
|
||||
@ -583,6 +586,10 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(null == obj && config.isIgnoreNullValue()){
|
||||
// 忽略空则不添加
|
||||
return false;
|
||||
}
|
||||
return this.rawList.add(obj);
|
||||
}
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ public class JSONConverter implements Converter {
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected static <T> T jsonConvert(final Type targetType, final Object value, final boolean ignoreError) throws ConvertException {
|
||||
if (JSONUtil.isNull(value)) {
|
||||
if (null == value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -91,7 +91,7 @@ public class JSONConverter implements Converter {
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected static <T> T jsonToBean(final Type targetType, final Object value, final boolean ignoreError) throws ConvertException {
|
||||
if (JSONUtil.isNull(value)) {
|
||||
if (null == value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.hutool.core.lang.getter.OptNullBasicTypeFromObjectGetter;
|
||||
import cn.hutool.core.text.StrUtil;
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
@ -32,10 +33,10 @@ public interface JSONGetter<K> extends OptNullBasicTypeFromObjectGetter<K> {
|
||||
* key对应值是否为{@code null}或无此key
|
||||
*
|
||||
* @param key 键
|
||||
* @return true 无此key或值为{@code null}或{@link JSONNull#NULL}返回{@code false},其它返回{@code true}
|
||||
* @return true 无此key或值为{@code null}返回{@code false},其它返回{@code true}
|
||||
*/
|
||||
default boolean isNull(final K key) {
|
||||
return JSONUtil.isNull(this.getObj(key));
|
||||
return ObjUtil.isNull(this.getObj(key));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -70,7 +71,7 @@ public interface JSONGetter<K> extends OptNullBasicTypeFromObjectGetter<K> {
|
||||
*/
|
||||
default JSONArray getJSONArray(final K key) {
|
||||
final Object object = this.getObj(key);
|
||||
if (JSONUtil.isNull(object)) {
|
||||
if (ObjUtil.isNull(object)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -89,7 +90,7 @@ public interface JSONGetter<K> extends OptNullBasicTypeFromObjectGetter<K> {
|
||||
*/
|
||||
default JSONObject getJSONObject(final K key) {
|
||||
final Object object = this.getObj(key);
|
||||
if (JSONUtil.isNull(object)) {
|
||||
if (ObjUtil.isNull(object)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -133,7 +134,7 @@ public interface JSONGetter<K> extends OptNullBasicTypeFromObjectGetter<K> {
|
||||
default Date getDate(final K key, final Date defaultValue) {
|
||||
// 默认转换
|
||||
final Object obj = getObj(key);
|
||||
if (JSONUtil.isNull(obj)) {
|
||||
if (ObjUtil.isNull(obj)) {
|
||||
return defaultValue;
|
||||
}
|
||||
if (obj instanceof Date) {
|
||||
@ -167,7 +168,7 @@ public interface JSONGetter<K> extends OptNullBasicTypeFromObjectGetter<K> {
|
||||
default LocalDateTime getLocalDateTime(final K key, final LocalDateTime defaultValue) {
|
||||
// 默认转换
|
||||
final Object obj = getObj(key);
|
||||
if (JSONUtil.isNull(obj)) {
|
||||
if (ObjUtil.isNull(obj)) {
|
||||
return defaultValue;
|
||||
}
|
||||
if (obj instanceof LocalDateTime) {
|
||||
@ -228,7 +229,7 @@ public interface JSONGetter<K> extends OptNullBasicTypeFromObjectGetter<K> {
|
||||
*/
|
||||
default <T> T get(final K key, final Class<T> type, final boolean ignoreError) throws ConvertException {
|
||||
final Object value = this.getObj(key);
|
||||
if (JSONUtil.isNull(value)) {
|
||||
if (ObjUtil.isNull(value)) {
|
||||
return null;
|
||||
}
|
||||
return JSONConverter.jsonConvert(type, value, ignoreError);
|
||||
|
@ -1,46 +0,0 @@
|
||||
package cn.hutool.json;
|
||||
|
||||
import cn.hutool.core.text.StrUtil;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 用于定义{@code null},与Javascript中null相对应<br>
|
||||
* Java中的{@code null}值在js中表示为undefined。
|
||||
*
|
||||
* @author Looly
|
||||
*/
|
||||
public class JSONNull implements Serializable {
|
||||
private static final long serialVersionUID = 2633815155870764938L;
|
||||
|
||||
/**
|
||||
* {@code NULL} 对象用于减少歧义来表示Java 中的{@code null} <br>
|
||||
* {@code NULL.equals(null)} 返回 {@code true}. <br>
|
||||
* {@code NULL.toString()} 返回 {@code "null"}.
|
||||
*/
|
||||
public static final JSONNull NULL = new JSONNull();
|
||||
|
||||
/**
|
||||
* A Null object is equal to the null value and to itself.
|
||||
* 对象与其本身和{@code null}值相等
|
||||
*
|
||||
* @param object An object to test for nullness.
|
||||
* @return true if the object parameter is the JSONObject.NULL object or null.
|
||||
*/
|
||||
@SuppressWarnings("EqualsWhichDoesntCheckParameterClass")
|
||||
@Override
|
||||
public boolean equals(final Object object) {
|
||||
return object == null || (object == this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the "null" string value.
|
||||
* 获得“null”字符串
|
||||
*
|
||||
* @return The string "null".
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return StrUtil.NULL;
|
||||
}
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
package cn.hutool.json;
|
||||
|
||||
import cn.hutool.core.bean.BeanPath;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.func.Filter;
|
||||
import cn.hutool.core.lang.mutable.MutableEntry;
|
||||
@ -182,19 +181,9 @@ public class JSONObject extends MapWrapper<String, Object> implements JSON, JSON
|
||||
return this.getOrDefault(key, defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getByPath(final String expression) {
|
||||
return BeanPath.of(expression).get(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getByPath(final String expression, final Class<T> resultType) {
|
||||
return JSONConverter.jsonConvert(resultType, getByPath(expression), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putByPath(final String expression, final Object value) {
|
||||
BeanPath.of(expression).set(this, value);
|
||||
return JSONConverter.jsonConvert(resultType, getByPath(expression), this.config.isIgnoreError());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -219,7 +208,23 @@ public class JSONObject extends MapWrapper<String, Object> implements JSON, JSON
|
||||
* @throws JSONException 值是无穷数字抛出此异常
|
||||
*/
|
||||
public JSONObject set(final String key, final Object value) throws JSONException {
|
||||
return set(key, value, null, false);
|
||||
put(key, value, null, false);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 一次性Put 键值对,如果key已经存在抛出异常,如果键值中有null值,忽略
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值对象,可以是以下类型: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or the JSONNull.NULL.
|
||||
* @param filter 键值对过滤编辑器,可以通过实现此接口,完成解析前对键值对的过滤和修改操作,{@code null}表示不过滤
|
||||
* @return this
|
||||
* @throws JSONException 值是无穷数字、键重复抛出异常
|
||||
* @since 5.8.0
|
||||
*/
|
||||
public JSONObject setOnce(final String key, final Object value, final Filter<MutableEntry<String, Object>> filter) throws JSONException {
|
||||
put(key, value, filter, true);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -238,32 +243,6 @@ public class JSONObject extends MapWrapper<String, Object> implements JSON, JSON
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 一次性Put 键值对,如果key已经存在抛出异常,如果键值中有null值,忽略
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值对象,可以是以下类型: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or the JSONNull.NULL.
|
||||
* @return this.
|
||||
* @throws JSONException 值是无穷数字、键重复抛出异常
|
||||
*/
|
||||
public JSONObject putOnce(final String key, final Object value) throws JSONException {
|
||||
return setOnce(key, value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 一次性Put 键值对,如果key已经存在抛出异常,如果键值中有null值,忽略
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值对象,可以是以下类型: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or the JSONNull.NULL.
|
||||
* @param filter 键值对过滤编辑器,可以通过实现此接口,完成解析前对键值对的过滤和修改操作,{@code null}表示不过滤
|
||||
* @return this
|
||||
* @throws JSONException 值是无穷数字、键重复抛出异常
|
||||
* @since 5.8.0
|
||||
*/
|
||||
public JSONObject setOnce(final String key, final Object value, final Filter<MutableEntry<String, Object>> filter) throws JSONException {
|
||||
return set(key, value, filter, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在键和值都为非空的情况下put到JSONObject中
|
||||
*
|
||||
@ -272,7 +251,7 @@ public class JSONObject extends MapWrapper<String, Object> implements JSON, JSON
|
||||
* @return this.
|
||||
* @throws JSONException 值是无穷数字
|
||||
*/
|
||||
public JSONObject putOpt(final String key, final Object value) throws JSONException {
|
||||
public JSONObject setOpt(final String key, final Object value) throws JSONException {
|
||||
if (key != null && value != null) {
|
||||
this.set(key, value);
|
||||
}
|
||||
@ -287,29 +266,12 @@ public class JSONObject extends MapWrapper<String, Object> implements JSON, JSON
|
||||
}
|
||||
|
||||
/**
|
||||
* 积累值。类似于set,当key对应value已经存在时,与value组成新的JSONArray. <br>
|
||||
* 如果只有一个值,此值就是value,如果多个值,则是添加到新的JSONArray中
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 被积累的值
|
||||
* @return this.
|
||||
* @throws JSONException 如果给定键为{@code null}或者键对应的值存在且为非JSONArray
|
||||
*/
|
||||
public JSONObject accumulate(final String key, final Object value) throws JSONException {
|
||||
InternalJSONUtil.testValidity(value);
|
||||
final Object object = this.getObj(key);
|
||||
if (object == null) {
|
||||
this.set(key, value);
|
||||
} else if (object instanceof JSONArray) {
|
||||
((JSONArray) object).set(value);
|
||||
} else {
|
||||
this.set(key, JSONUtil.createArray(this.config).set(object).set(value));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 追加值,如果key无对应值,就添加一个JSONArray,其元素只有value,如果值已经是一个JSONArray,则添加到值JSONArray中。
|
||||
* 追加值.
|
||||
* <ul>
|
||||
* <li>如果键值对不存在或对应值为{@code null},则value为单独值</li>
|
||||
* <li>如果值是一个{@link JSONArray},追加之</li>
|
||||
* <li>如果值是一个其他值,则和旧值共同组合为一个{@link JSONArray}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
@ -320,11 +282,11 @@ public class JSONObject extends MapWrapper<String, Object> implements JSON, JSON
|
||||
InternalJSONUtil.testValidity(value);
|
||||
final Object object = this.getObj(key);
|
||||
if (object == null) {
|
||||
this.set(key, new JSONArray(this.config).set(value));
|
||||
this.set(key, value);
|
||||
} else if (object instanceof JSONArray) {
|
||||
this.set(key, ((JSONArray) object).set(value));
|
||||
((JSONArray) object).set(value);
|
||||
} else {
|
||||
throw new JSONException("JSONObject [" + key + "] is not a JSONArray.");
|
||||
this.set(key, JSONUtil.createArray(this.config).set(object).set(value));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@ -435,13 +397,13 @@ public class JSONObject extends MapWrapper<String, Object> implements JSON, JSON
|
||||
* @param value 值对象. 可以是以下类型: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or the JSONNull.NULL.
|
||||
* @param filter 键值对过滤编辑器,可以通过实现此接口,完成解析前对键值对的过滤和修改操作,{@code null}表示不过滤
|
||||
* @param checkDuplicate 是否检查重复键,如果为{@code true},则出现重复键时抛出{@link JSONException}异常
|
||||
* @return this.
|
||||
* @return 旧值
|
||||
* @throws JSONException 值是无穷数字抛出此异常
|
||||
* @since 5.8.0
|
||||
*/
|
||||
private Object put(String key, Object value, final Filter<MutableEntry<String, Object>> filter, final boolean checkDuplicate) throws JSONException {
|
||||
if (null == key) {
|
||||
return this;
|
||||
return null;
|
||||
}
|
||||
|
||||
// 添加前置过滤,通过MutablePair实现过滤、修改键值对等
|
||||
@ -453,12 +415,12 @@ public class JSONObject extends MapWrapper<String, Object> implements JSON, JSON
|
||||
value = pair.getValue();
|
||||
} else {
|
||||
// 键值对被过滤
|
||||
return this;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
final boolean ignoreNullValue = this.config.isIgnoreNullValue();
|
||||
if (ObjUtil.isNull(value) && ignoreNullValue) {
|
||||
if (null == value && ignoreNullValue) {
|
||||
// 忽略值模式下如果值为空清除key
|
||||
return this.remove(key);
|
||||
} else if (checkDuplicate && containsKey(key)) {
|
||||
|
@ -106,7 +106,7 @@ public class JSONParser {
|
||||
for (; ; ) {
|
||||
if (x.nextClean() == ',') {
|
||||
x.back();
|
||||
jsonArray.addRaw(JSONNull.NULL, filter);
|
||||
jsonArray.addRaw(null, filter);
|
||||
} else {
|
||||
x.back();
|
||||
jsonArray.addRaw(x.nextValue(), filter);
|
||||
|
@ -411,7 +411,7 @@ public class JSONTokener {
|
||||
while (true) {
|
||||
if (this.nextClean() == ',') {
|
||||
this.back();
|
||||
jsonArray.add(JSONNull.NULL);
|
||||
jsonArray.add(null);
|
||||
} else {
|
||||
this.back();
|
||||
jsonArray.add(this.nextValue());
|
||||
|
@ -716,7 +716,7 @@ public class JSONUtil {
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public static Object wrap(final Object object, final JSONConfig jsonConfig) {
|
||||
if (object == null) {
|
||||
return jsonConfig.isIgnoreNullValue() ? null : JSONNull.NULL;
|
||||
return null;
|
||||
}
|
||||
if (object instanceof JSON //
|
||||
|| ObjUtil.isNull(object) //
|
||||
@ -836,22 +836,6 @@ public class JSONUtil {
|
||||
return StrUtil.isWrap(StrUtil.trim(str), '[', ']');
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为null对象,null的情况包括:
|
||||
*
|
||||
* <pre>
|
||||
* 1. {@code null}
|
||||
* 2. {@link JSONNull}
|
||||
* </pre>
|
||||
*
|
||||
* @param obj 对象
|
||||
* @return 是否为null
|
||||
* @since 4.5.7
|
||||
*/
|
||||
public static boolean isNull(final Object obj) {
|
||||
return null == obj || obj instanceof JSONNull;
|
||||
}
|
||||
|
||||
/**
|
||||
* XML转JSONObject<br>
|
||||
* 转换过程中一些信息可能会丢失,JSON中无法区分节点和属性,相同的节点将被处理为JSONArray。
|
||||
|
@ -14,7 +14,6 @@ import cn.hutool.json.JSON;
|
||||
import cn.hutool.json.JSONArray;
|
||||
import cn.hutool.json.JSONConfig;
|
||||
import cn.hutool.json.JSONException;
|
||||
import cn.hutool.json.JSONNull;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONString;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
@ -96,6 +95,7 @@ public class JSONWriter extends Writer {
|
||||
* @return this
|
||||
*/
|
||||
public JSONWriter beginObj() {
|
||||
//noinspection resource
|
||||
writeRaw(CharUtil.DELIM_START);
|
||||
return this;
|
||||
}
|
||||
@ -106,6 +106,7 @@ public class JSONWriter extends Writer {
|
||||
* @return this
|
||||
*/
|
||||
public JSONWriter beginArray() {
|
||||
//noinspection resource
|
||||
writeRaw(CharUtil.BRACKET_START);
|
||||
arrayMode = true;
|
||||
return this;
|
||||
@ -118,7 +119,9 @@ public class JSONWriter extends Writer {
|
||||
*/
|
||||
public JSONWriter end() {
|
||||
// 换行缩进
|
||||
//noinspection resource
|
||||
writeLF().writeSpace(indent);
|
||||
//noinspection resource
|
||||
writeRaw(arrayMode ? CharUtil.BRACKET_END : CharUtil.DELIM_END);
|
||||
flush();
|
||||
arrayMode = false;
|
||||
@ -135,22 +138,24 @@ public class JSONWriter extends Writer {
|
||||
*/
|
||||
public JSONWriter writeKey(final String key) {
|
||||
if (needSeparator) {
|
||||
//noinspection resource
|
||||
writeRaw(CharUtil.COMMA);
|
||||
}
|
||||
// 换行缩进
|
||||
//noinspection resource
|
||||
writeLF().writeSpace(indentFactor + indent);
|
||||
return writeRaw(JSONUtil.quote(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* 写出值,自动处理分隔符和缩进,自动判断类型,并根据不同类型写出特定格式的值<br>
|
||||
* 如果写出的值为{@code null}或者{@link JSONNull},且配置忽略null,则跳过。
|
||||
* 如果写出的值为{@code null},且配置忽略null,则跳过。
|
||||
*
|
||||
* @param value 值
|
||||
* @return this
|
||||
*/
|
||||
public JSONWriter writeValue(final Object value) {
|
||||
if(JSONUtil.isNull(value) && config.isIgnoreNullValue()){
|
||||
if (null == value && config.isIgnoreNullValue()) {
|
||||
return this;
|
||||
}
|
||||
return writeValueDirect(value);
|
||||
@ -159,16 +164,17 @@ public class JSONWriter extends Writer {
|
||||
/**
|
||||
* 写出字段名及字段值,如果字段值是{@code null}且忽略null值,则不写出任何内容
|
||||
*
|
||||
* @param key 字段名
|
||||
* @param key 字段名
|
||||
* @param value 字段值
|
||||
* @return this
|
||||
* @since 5.7.6
|
||||
*/
|
||||
public JSONWriter writeField(final String key, final Object value){
|
||||
if(JSONUtil.isNull(value) && config.isIgnoreNullValue()){
|
||||
public JSONWriter writeField(final String key, final Object value) {
|
||||
if (null == value && config.isIgnoreNullValue()) {
|
||||
return this;
|
||||
}
|
||||
|
||||
//noinspection resource
|
||||
return writeKey(key).writeValueDirect(value);
|
||||
}
|
||||
|
||||
@ -192,6 +198,7 @@ public class JSONWriter extends Writer {
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------ Private methods
|
||||
|
||||
/**
|
||||
* 写出值,自动处理分隔符和缩进,自动判断类型,并根据不同类型写出特定格式的值
|
||||
*
|
||||
@ -201,11 +208,14 @@ public class JSONWriter extends Writer {
|
||||
private JSONWriter writeValueDirect(final Object value) {
|
||||
if (arrayMode) {
|
||||
if (needSeparator) {
|
||||
//noinspection resource
|
||||
writeRaw(CharUtil.COMMA);
|
||||
}
|
||||
// 换行缩进
|
||||
//noinspection resource
|
||||
writeLF().writeSpace(indentFactor + indent);
|
||||
} else {
|
||||
//noinspection resource
|
||||
writeRaw(CharUtil.COLON).writeSpace(1);
|
||||
}
|
||||
needSeparator = true;
|
||||
@ -220,24 +230,26 @@ public class JSONWriter extends Writer {
|
||||
*/
|
||||
private JSONWriter writeObjValue(final Object value) {
|
||||
final int indent = indentFactor + this.indent;
|
||||
if (value == null || value instanceof JSONNull) {
|
||||
writeRaw(JSONNull.NULL.toString());
|
||||
if (value == null) {
|
||||
//noinspection resource
|
||||
writeRaw(StrUtil.NULL);
|
||||
} else if (value instanceof JSON) {
|
||||
((JSON) value).write(writer, indentFactor, indent);
|
||||
} 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)) {
|
||||
if(value instanceof byte[]){
|
||||
if (value instanceof byte[]) {
|
||||
// issue#I59LW4
|
||||
// json内容中的bytes默认转为Base64
|
||||
writeStrValue(Base64.encode((byte[]) value));
|
||||
}else{
|
||||
} else {
|
||||
new JSONArray(value).write(writer, indentFactor, indent);
|
||||
}
|
||||
} else if (value instanceof Number) {
|
||||
writeNumberValue((Number) value);
|
||||
} else if (value instanceof Date || value instanceof Calendar || value instanceof TemporalAccessor) {
|
||||
final String format = (null == config) ? null : config.getDateFormat();
|
||||
//noinspection resource
|
||||
writeRaw(formatDate(value, format));
|
||||
} else if (value instanceof Boolean) {
|
||||
writeBooleanValue((Boolean) value);
|
||||
@ -260,6 +272,7 @@ public class JSONWriter extends Writer {
|
||||
private void writeNumberValue(final Number number) {
|
||||
// since 5.6.2可配置是否去除末尾多余0,例如如果为true,5.0返回5
|
||||
final boolean isStripTrailingZeros = null == config || config.isStripTrailingZeros();
|
||||
//noinspection resource
|
||||
writeRaw(NumberUtil.toStr(number, isStripTrailingZeros));
|
||||
}
|
||||
|
||||
@ -269,6 +282,7 @@ public class JSONWriter extends Writer {
|
||||
* @param value Boolean值
|
||||
*/
|
||||
private void writeBooleanValue(final Boolean value) {
|
||||
//noinspection resource
|
||||
writeRaw(value.toString());
|
||||
}
|
||||
|
||||
@ -287,6 +301,7 @@ public class JSONWriter extends Writer {
|
||||
throw new JSONException(e);
|
||||
}
|
||||
if (null != valueStr) {
|
||||
//noinspection resource
|
||||
writeRaw(valueStr);
|
||||
} else {
|
||||
writeStrValue(jsonString.toString());
|
||||
@ -317,6 +332,7 @@ public class JSONWriter extends Writer {
|
||||
private void writeSpace(final int count) {
|
||||
if (indentFactor > 0) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
//noinspection resource
|
||||
writeRaw(CharUtil.SPACE);
|
||||
}
|
||||
}
|
||||
@ -329,6 +345,7 @@ public class JSONWriter extends Writer {
|
||||
*/
|
||||
private JSONWriter writeLF() {
|
||||
if (indentFactor > 0) {
|
||||
//noinspection resource
|
||||
writeRaw(CharUtil.LF);
|
||||
}
|
||||
return this;
|
||||
|
@ -1,5 +1,6 @@
|
||||
package cn.hutool.json.xml;
|
||||
|
||||
import cn.hutool.core.text.StrUtil;
|
||||
import cn.hutool.json.InternalJSONUtil;
|
||||
import cn.hutool.json.JSONException;
|
||||
import cn.hutool.json.JSONObject;
|
||||
@ -63,7 +64,7 @@ public class JSONXMLParser {
|
||||
if (x.next() == '[') {
|
||||
string = x.nextCDATA();
|
||||
if (string.length() > 0) {
|
||||
context.accumulate("content", string);
|
||||
context.append("content", string);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -126,10 +127,10 @@ public class JSONXMLParser {
|
||||
if (!(token instanceof String)) {
|
||||
throw x.syntaxError("Missing value");
|
||||
}
|
||||
jsonobject.accumulate(string, keepStrings ? token : InternalJSONUtil.stringToValue((String) token));
|
||||
jsonobject.append(string, keepStrings ? token : InternalJSONUtil.stringToValue((String) token));
|
||||
token = null;
|
||||
} else {
|
||||
jsonobject.accumulate(string, "");
|
||||
jsonobject.append(string, "");
|
||||
}
|
||||
|
||||
} else if (token == XML.SLASH) {
|
||||
@ -138,9 +139,9 @@ public class JSONXMLParser {
|
||||
throw x.syntaxError("Misshaped tag");
|
||||
}
|
||||
if (jsonobject.size() > 0) {
|
||||
context.accumulate(tagName, jsonobject);
|
||||
context.append(tagName, jsonobject);
|
||||
} else {
|
||||
context.accumulate(tagName, "");
|
||||
context.append(tagName, StrUtil.EMPTY);
|
||||
}
|
||||
return false;
|
||||
|
||||
@ -156,18 +157,18 @@ public class JSONXMLParser {
|
||||
} else if (token instanceof String) {
|
||||
string = (String) token;
|
||||
if (string.length() > 0) {
|
||||
jsonobject.accumulate("content", keepStrings ? token : InternalJSONUtil.stringToValue(string));
|
||||
jsonobject.append("content", keepStrings ? token : InternalJSONUtil.stringToValue(string));
|
||||
}
|
||||
|
||||
} else if (token == XML.LT) {
|
||||
// Nested element
|
||||
if (parse(x, jsonobject, tagName, keepStrings)) {
|
||||
if (jsonobject.size() == 0) {
|
||||
context.accumulate(tagName, "");
|
||||
context.append(tagName, "");
|
||||
} else if (jsonobject.size() == 1 && jsonobject.get("content") != null) {
|
||||
context.accumulate(tagName, jsonobject.get("content"));
|
||||
context.append(tagName, jsonobject.get("content"));
|
||||
} else {
|
||||
context.accumulate(tagName, jsonobject);
|
||||
context.append(tagName, jsonobject);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ public class JSONArrayTest {
|
||||
@Test
|
||||
public void toListWithNullTest() {
|
||||
final String json = "[null,{'akey':'avalue','bkey':'bvalue'}]";
|
||||
final JSONArray ja = JSONUtil.parseArray(json);
|
||||
final JSONArray ja = JSONUtil.parseArray(json, JSONConfig.of().setIgnoreNullValue(false));
|
||||
|
||||
final List<KeyBean> list = ja.toList(KeyBean.class);
|
||||
Assert.assertNull(list.get(0));
|
||||
@ -218,8 +218,13 @@ public class JSONArrayTest {
|
||||
|
||||
@Test
|
||||
public void putToIndexTest(){
|
||||
final JSONArray jsonArray = new JSONArray();
|
||||
jsonArray.put(3, "test");
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
jsonArray.set(3, "test");
|
||||
// 默认忽略null值,因此空位无值,只有一个值
|
||||
Assert.assertEquals(1, jsonArray.size());
|
||||
|
||||
jsonArray = new JSONArray(JSONConfig.of().setIgnoreNullValue(false));
|
||||
jsonArray.set(3, "test");
|
||||
// 第三个位置插入值,0~2都是null
|
||||
Assert.assertEquals(4, jsonArray.size());
|
||||
}
|
||||
|
@ -12,9 +12,9 @@ public class JSONNullTest {
|
||||
" \"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());
|
||||
Assert.assertNull(bodyjson.get("device_model"));
|
||||
Assert.assertNull(bodyjson.get("device_status_date"));
|
||||
Assert.assertNull(bodyjson.get("imsi"));
|
||||
|
||||
bodyjson.getConfig().setIgnoreNullValue(true);
|
||||
Assert.assertEquals("{\"act_date\":\"2021-07-23T06:23:26.000+00:00\"}", bodyjson.toString());
|
||||
@ -31,4 +31,26 @@ public class JSONNullTest {
|
||||
Assert.assertFalse(bodyjson.containsKey("device_status_date"));
|
||||
Assert.assertFalse(bodyjson.containsKey("imsi"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setNullTest(){
|
||||
// 忽略null
|
||||
String json1 = JSONUtil.createObj().set("key1", null).toString();
|
||||
Assert.assertEquals("{}", json1);
|
||||
|
||||
// 不忽略null
|
||||
json1 = JSONUtil.createObj(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();
|
||||
Assert.assertEquals("[]", json1);
|
||||
|
||||
// 不忽略null
|
||||
json1 = JSONUtil.createArray(JSONConfig.of().setIgnoreNullValue(false)).set(null).toString();
|
||||
Assert.assertEquals("[null]", json1);
|
||||
}
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ public class JSONObjectTest {
|
||||
Assert.assertEquals(jsonObject.get("d"), true);
|
||||
|
||||
Assert.assertTrue(jsonObject.containsKey("e"));
|
||||
Assert.assertEquals(jsonObject.get("e"), JSONNull.NULL);
|
||||
Assert.assertNull(jsonObject.get("e"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -460,7 +460,7 @@ public class JSONObjectTest {
|
||||
json.append("date", DateUtil.parse("2020-06-05 11:16:11"));
|
||||
json.append("bbb", "222");
|
||||
json.append("aaa", "123");
|
||||
Assert.assertEquals("{\"date\":[\"2020-06-05 11:16:11\"],\"bbb\":[\"222\"],\"aaa\":[\"123\"]}", json.toString());
|
||||
Assert.assertEquals("{\"date\":\"2020-06-05 11:16:11\",\"bbb\":\"222\",\"aaa\":\"123\"}", json.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -612,14 +612,14 @@ public class JSONObjectTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void accumulateTest() {
|
||||
final JSONObject jsonObject = JSONUtil.createObj().accumulate("key1", "value1");
|
||||
public void appendTest() {
|
||||
final JSONObject jsonObject = JSONUtil.createObj().append("key1", "value1");
|
||||
Assert.assertEquals("{\"key1\":\"value1\"}", jsonObject.toString());
|
||||
|
||||
jsonObject.accumulate("key1", "value2");
|
||||
jsonObject.append("key1", "value2");
|
||||
Assert.assertEquals("{\"key1\":[\"value1\",\"value2\"]}", jsonObject.toString());
|
||||
|
||||
jsonObject.accumulate("key1", "value3");
|
||||
jsonObject.append("key1", "value3");
|
||||
Assert.assertEquals("{\"key1\":[\"value1\",\"value2\",\"value3\"]}", jsonObject.toString());
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user