This commit is contained in:
Looly 2024-09-27 14:11:15 +08:00
parent 1c18ccf660
commit 499c3cf4df
13 changed files with 326 additions and 187 deletions

View File

@ -24,8 +24,8 @@ import org.dromara.hutool.core.map.CaseInsensitiveTreeMap;
import org.dromara.hutool.core.text.CharUtil;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.core.util.ObjUtil;
import org.dromara.hutool.json.serializer.JSONMapper;
import org.dromara.hutool.json.reader.JSONTokener;
import org.dromara.hutool.json.serializer.JSONMapper;
import java.io.IOException;
import java.math.BigDecimal;
@ -102,8 +102,8 @@ public final class InternalJSONUtil {
*/
static boolean defaultIgnoreNullValue(final Object obj) {
return (!(obj instanceof CharSequence))//
&& (!(obj instanceof JSONTokener))//
&& (!(obj instanceof Map));
&& (!(obj instanceof JSONTokener))//
&& (!(obj instanceof Map));
}
/**
@ -114,12 +114,13 @@ public final class InternalJSONUtil {
* @since 5.8.0
*/
public static CopyOptions toCopyOptions(final JSONConfig config) {
final JSONMapper mapper = JSONFactory.of(config, null).getMapper();
return CopyOptions.of()
.setIgnoreCase(config.isIgnoreCase())
.setIgnoreError(config.isIgnoreError())
.setIgnoreNullValue(config.isIgnoreNullValue())
.setTransientSupport(config.isTransientSupport())
.setConverter((targetType, value) -> JSONMapper.of(config, null).map(value));
.setIgnoreCase(config.isIgnoreCase())
.setIgnoreError(config.isIgnoreError())
.setIgnoreNullValue(config.isIgnoreNullValue())
.setTransientSupport(config.isTransientSupport())
.setConverter((targetType, value) -> mapper.map(value));
}
/**
@ -153,7 +154,7 @@ public final class InternalJSONUtil {
* 为了能在HTML中较好的显示会将&lt;/转义为&lt;\/<br>
* JSON字符串中不能包含控制字符和未经转义的引号和反斜杠
*
* @param str 字符串
* @param str 字符串
* @param appendable {@link Appendable}
* @throws IORuntimeException IO异常
*/
@ -166,9 +167,9 @@ public final class InternalJSONUtil {
* 为了能在HTML中较好的显示会将&lt;/转义为&lt;\/<br>
* JSON字符串中不能包含控制字符和未经转义的引号和反斜杠
*
* @param str 字符串
* @param str 字符串
* @param appendable {@link Appendable}
* @param isWrap 是否使用双引号包装字符串
* @param isWrap 是否使用双引号包装字符串
* @return Writer
* @throws IORuntimeException IO异常
* @since 3.3.1
@ -206,13 +207,16 @@ public final class InternalJSONUtil {
* 根据配置创建对应的原始Map
*
* @param capacity 初始大小
* @param config JSON配置项{@code null}则使用默认配置
* @param factory JSON工厂{@code null}则使用默认配置
* @return Map
*/
static Map<String, JSON> createRawMap(final int capacity, final JSONConfig config) {
final Map<String, JSON> rawHashMap;
static Map<String, JSON> createRawMap(final int capacity, final JSONFactory factory) {
final JSONConfig config = ObjUtil.apply(factory, JSONFactory::getConfig);
final boolean ignoreCase = ObjUtil.defaultIfNull(config, JSONConfig::isIgnoreCase, false);
final Comparator<String> keyComparator = ObjUtil.apply(config, JSONConfig::getKeyComparator);
if (null != config && config.isIgnoreCase()) {
final Map<String, JSON> rawHashMap;
if (ignoreCase) {
if (null != keyComparator) {
rawHashMap = new CaseInsensitiveTreeMap<>(keyComparator);
} else {
@ -295,10 +299,10 @@ public final class InternalJSONUtil {
return "\\r";
default:
if (c < CharUtil.SPACE || //
(c >= '\u0080' && c <= '\u00a0') || //
(c >= '\u2000' && c <= '\u2010') || //
(c >= '\u2028' && c <= '\u202F') || //
(c >= '\u2066' && c <= '\u206F')//
(c >= '\u0080' && c <= '\u00a0') || //
(c >= '\u2000' && c <= '\u2010') || //
(c >= '\u2028' && c <= '\u202F') || //
(c >= '\u2066' && c <= '\u206F')//
) {
return HexUtil.toUnicodeHex(c);
} else {

View File

@ -18,8 +18,6 @@ package org.dromara.hutool.json;
import org.dromara.hutool.core.bean.path.BeanPath;
import org.dromara.hutool.core.lang.mutable.MutableEntry;
import org.dromara.hutool.json.serializer.JSONMapper;
import org.dromara.hutool.json.support.JSONNodeBeanFactory;
import org.dromara.hutool.json.writer.JSONWriter;
import java.io.Serializable;
@ -147,7 +145,7 @@ public interface JSON extends Serializable {
return null;
}
return JSONMapper.of(config(), null).toBean(json, resultType);
return json.toBean(resultType);
}
/**
@ -171,7 +169,7 @@ public interface JSON extends Serializable {
* @see BeanPath#getValue(Object)
*/
default JSON getByPath(final String expression) {
return (JSON) BeanPath.of(expression).getValue(this);
return (JSON) JSONFactory.of(config(), null).ofBeanPath(expression).getValue(this);
}
/**
@ -196,7 +194,7 @@ public interface JSON extends Serializable {
* @param value
*/
default void putByPath(final String expression, final Object value) {
BeanPath.of(expression, new JSONNodeBeanFactory(config())).setValue(this, value);
JSONFactory.of(config(), null).ofBeanPath(expression).setValue(this, value);
}
/**
@ -214,25 +212,25 @@ public interface JSON extends Serializable {
* 格式化输出JSON字符串
*
* @param indentFactor 每层缩进空格数
* @param predicate 过滤器用于过滤不需要的键值对
* @return JSON字符串
* @throws JSONException 包含非法数抛出此异常
*/
default String toJSONString(final int indentFactor, final Predicate<MutableEntry<Object, Object>> predicate) throws JSONException {
final JSONWriter jsonWriter = JSONWriter.of(new StringBuilder(), indentFactor, 0, config()).setPredicate(predicate);
this.write(jsonWriter);
return jsonWriter.toString();
default String toJSONString(final int indentFactor) throws JSONException {
return toJSONString(indentFactor, null);
}
/**
* 格式化输出JSON字符串
*
* @param indentFactor 每层缩进空格数
* @param predicate 过滤器用于过滤不需要的键值对
* @return JSON字符串
* @throws JSONException 包含非法数抛出此异常
*/
default String toJSONString(final int indentFactor) throws JSONException {
return toJSONString(indentFactor, null);
default String toJSONString(final int indentFactor, final Predicate<MutableEntry<Object, Object>> predicate) throws JSONException {
final JSONWriter jsonWriter = JSONFactory.of(config(), predicate).ofWriter(new StringBuilder(), indentFactor);
this.write(jsonWriter);
return jsonWriter.toString();
}
/**
@ -252,6 +250,6 @@ public interface JSON extends Serializable {
* @return 实体类对象
*/
default <T> T toBean(final Type type) {
return JSONMapper.of(config(), null).toBean(this, type);
return JSONFactory.of(config(), null).toBean(this, type);
}
}

View File

@ -20,8 +20,6 @@ import org.dromara.hutool.core.collection.CollUtil;
import org.dromara.hutool.core.collection.ListWrapper;
import org.dromara.hutool.core.lang.Validator;
import org.dromara.hutool.core.lang.mutable.MutableEntry;
import org.dromara.hutool.core.util.ObjUtil;
import org.dromara.hutool.json.serializer.JSONMapper;
import org.dromara.hutool.json.serializer.impl.ArrayTypeAdapter;
import org.dromara.hutool.json.serializer.impl.IterTypeAdapter;
import org.dromara.hutool.json.writer.JSONWriter;
@ -47,11 +45,7 @@ public class JSONArray extends ListWrapper<JSON> implements JSON, JSONGetter<Int
*/
public static final int DEFAULT_CAPACITY = 10;
/**
* 配置项
*/
private final JSONConfig config;
private final JSONMapper mapper;
private final JSONFactory factory;
// region ----- Constructors
@ -68,10 +62,9 @@ public class JSONArray extends ListWrapper<JSON> implements JSON, JSONGetter<Int
* 默认使用{@link ArrayList} 实现
*
* @param initialCapacity 初始大小
* @since 3.2.2
*/
public JSONArray(final int initialCapacity) {
this(initialCapacity, JSONConfig.of());
this(initialCapacity, JSONFactory.getInstance());
}
/**
@ -91,18 +84,27 @@ public class JSONArray extends ListWrapper<JSON> implements JSON, JSONGetter<Int
*
* @param initialCapacity 初始大小
* @param config JSON配置项
* @since 4.1.19
*/
public JSONArray(final int initialCapacity, final JSONConfig config) {
this(initialCapacity, JSONFactory.of(config, null));
}
/**
* 构造<br>
* 默认使用{@link ArrayList} 实现
*
* @param initialCapacity 初始大小
* @param factory JSON工厂
*/
public JSONArray(final int initialCapacity, final JSONFactory factory) {
super(new ArrayList<>(initialCapacity));
this.config = ObjUtil.defaultIfNull(config, JSONConfig::of);
this.mapper = JSONMapper.of(config, null);
this.factory = factory;
}
// endregion
@Override
public JSONConfig config() {
return this.config;
return factory.getConfig();
}
@Override
@ -119,7 +121,7 @@ public class JSONArray extends ListWrapper<JSON> implements JSON, JSONGetter<Int
* @since 5.2.5
*/
public JSONArray set(final Object value) {
this.add(mapper.map(value));
this.add(this.factory.getMapper().map(value));
return this;
}
@ -134,7 +136,7 @@ public class JSONArray extends ListWrapper<JSON> implements JSON, JSONGetter<Int
if (names == null || names.size() == 0 || this.size() == 0) {
return null;
}
final JSONObject jo = new JSONObject(this.config);
final JSONObject jo = this.factory.ofObj();
for (int i = 0; i < names.size(); i += 1) {
jo.set(names.getStr(i), this.getObj(i));
}
@ -154,7 +156,7 @@ public class JSONArray extends ListWrapper<JSON> implements JSON, JSONGetter<Int
}
final List<JSON> list = new ArrayList<>(c.size());
for (final JSON json : c) {
if (null == json && config.isIgnoreNullValue()) {
if (null == json && config().isIgnoreNullValue()) {
continue;
}
list.add(json);
@ -170,7 +172,7 @@ public class JSONArray extends ListWrapper<JSON> implements JSON, JSONGetter<Int
* @return 替换的值即之前的值
*/
public JSON setValue(final int index, final Object element) {
return set(index, mapper.map(element));
return set(index, this.factory.getMapper().map(element));
}
/**
@ -187,7 +189,7 @@ public class JSONArray extends ListWrapper<JSON> implements JSON, JSONGetter<Int
add(index, element);
return null;
}
if (null == element && config.isIgnoreNullValue()) {
if (null == element && config().isIgnoreNullValue()) {
return null;
}
return this.raw.set(index, element);
@ -195,7 +197,8 @@ public class JSONArray extends ListWrapper<JSON> implements JSON, JSONGetter<Int
@Override
public void add(int index, final JSON element) {
if (null == element && config.isIgnoreNullValue()) {
final boolean ignoreNullValue = config().isIgnoreNullValue();
if (null == element && ignoreNullValue) {
return;
}
if (index < this.size()) {
@ -205,7 +208,7 @@ public class JSONArray extends ListWrapper<JSON> implements JSON, JSONGetter<Int
this.raw.add(index, element);
} else {
// issue#3286, 如果用户指定的index太大容易造成Java heap space错误
if (!config.isIgnoreNullValue()) {
if (!ignoreNullValue) {
// issue#3286, 增加安全检查最多增加10倍
Validator.checkIndexLimit(index, (this.size() + 1) * 10);
while (index != this.size()) {

View File

@ -16,9 +16,14 @@
package org.dromara.hutool.json;
import org.dromara.hutool.core.bean.path.BeanPath;
import org.dromara.hutool.core.lang.mutable.MutableEntry;
import org.dromara.hutool.core.util.ObjUtil;
import org.dromara.hutool.json.reader.JSONParser;
import org.dromara.hutool.json.reader.JSONTokener;
import org.dromara.hutool.json.serializer.JSONMapper;
import org.dromara.hutool.json.support.JSONNodeBeanFactory;
import org.dromara.hutool.json.writer.JSONWriter;
import java.io.ByteArrayInputStream;
import java.lang.reflect.Type;
@ -32,6 +37,22 @@ import java.util.function.Predicate;
*/
public class JSONFactory {
/**
* 单例
*/
private static class InstanceHolder {
public static final JSONFactory INSTANCE = of(JSONConfig.of(), null);
}
/**
* 获取单例
*
* @return 单例
*/
public static JSONFactory getInstance() {
return InstanceHolder.INSTANCE;
}
/**
* 创建JSON工厂
*
@ -44,8 +65,12 @@ public class JSONFactory {
}
private final JSONConfig config;
/**
* 过滤器用于过滤或修改键值对返回null表示忽略此键值对返回非null表示修改后返回<br>
* entry中key在JSONObject中为name在JSONArray中为index
*/
private final Predicate<MutableEntry<Object, Object>> predicate;
private final JSONMapper mapper;
private volatile JSONMapper mapper;
/**
* 构造
@ -56,16 +81,41 @@ public class JSONFactory {
public JSONFactory(final JSONConfig config, final Predicate<MutableEntry<Object, Object>> predicate) {
this.config = ObjUtil.defaultIfNull(config, JSONConfig::of);
this.predicate = predicate;
this.mapper = JSONMapper.of(config, predicate);
}
/**
* 获取{@link JSONMapper}
* 获取配置项
*
* @return 配置项
*/
public JSONConfig getConfig() {
return this.config;
}
/**
* 获取键值对过滤器
*
* @return 键值对过滤器
*/
public Predicate<MutableEntry<Object, Object>> getPredicate() {
return this.predicate;
}
/**
* 获取{@link JSONMapper}用于实现Bean和JSON的转换<br>
* 此方法使用双重检查锁实现懒加载模式只有mapper被使用时才初始化
*
* @return {@link JSONMapper}
*/
public JSONMapper getMapper() {
return mapper;
if (null == this.mapper) {
synchronized (this) {
if (null == this.mapper) {
this.mapper = JSONMapper.of(this);
}
}
}
return this.mapper;
}
// region ----- of
@ -76,7 +126,7 @@ public class JSONFactory {
* @return JSONObject
*/
public JSONObject ofObj() {
return new JSONObject(this.config);
return new JSONObject(JSONObject.DEFAULT_CAPACITY, this);
}
/**
@ -85,7 +135,7 @@ public class JSONFactory {
* @return JSONArray
*/
public JSONArray ofArray() {
return new JSONArray(this.config);
return new JSONArray(JSONArray.DEFAULT_CAPACITY, this);
}
/**
@ -95,7 +145,59 @@ public class JSONFactory {
* @return JSONPrimitive
*/
public JSONPrimitive ofPrimitive(final Object value) {
return new JSONPrimitive(value, this.config);
return new JSONPrimitive(value, this);
}
/**
* 创建{@link JSONParser}用于JSON解析
*
* @param tokener {@link JSONTokener}
* @return {@link JSONParser}
*/
public JSONParser ofParser(final JSONTokener tokener){
return JSONParser.of(tokener, this.config).setPredicate(this.predicate);
}
/**
* 创建{@link JSONWriter}用于JSON写出
*
* @param appendable {@link Appendable}
* @return {@link JSONWriter}
*/
public JSONWriter ofWriter(final Appendable appendable) {
return ofWriter(appendable, 0);
}
/**
* 创建{@link JSONWriter}用于JSON写出
*
* @param appendable {@link Appendable}
* @param prettyPrint 是否格式化输出
* @return {@link JSONWriter}
*/
public JSONWriter ofWriter(final Appendable appendable, final boolean prettyPrint) {
return ofWriter(appendable, prettyPrint ? 2 : 0);
}
/**
* 创建{@link JSONWriter}用于JSON写出
*
* @param appendable {@link Appendable}
* @param indentFactor 缩进因子定义每一级别增加的缩进量用于格式化输出
* @return {@link JSONWriter}
*/
public JSONWriter ofWriter(final Appendable appendable, final int indentFactor) {
return JSONWriter.of(appendable, indentFactor, config, predicate);
}
/**
* 创建BeanPath用于使用路径方式访问或设置值
*
* @param expression BeanPath表达式
* @return BeanPath
*/
public BeanPath<JSON> ofBeanPath(final String expression) {
return BeanPath.of(expression, new JSONNodeBeanFactory(config));
}
// endregion
@ -112,11 +214,11 @@ public class JSONFactory {
obj = new ByteArrayInputStream((byte[]) obj);
}
final JSONMapper jsonMapper = JSONMapper.of(config, predicate);
final JSONMapper mapper = getMapper();
if (obj instanceof CharSequence) {
return (JSONObject) jsonMapper.map((CharSequence) obj);
return (JSONObject) mapper.map((CharSequence) obj);
}
return jsonMapper.mapObj(obj);
return mapper.mapObj(obj);
}
/**
@ -127,20 +229,19 @@ public class JSONFactory {
* <li>其它支持和自定义的对象如集合数组等</li>
* </ul>
*
* @param obj 数组或集合对象
* @param obj 数组或集合对象
* @return JSONArray
*/
public JSONArray parseArray(final Object obj) {
final JSONMapper mapper = getMapper();
if (obj instanceof JSONObject) {
final JSONMapper jsonMapper = JSONMapper.of(config, predicate);
return jsonMapper.mapFromJSONObject((JSONObject) obj);
return mapper.mapFromJSONObject((JSONObject) obj);
}
final JSONMapper jsonMapper = JSONMapper.of(config, predicate);
if (obj instanceof CharSequence) {
return (JSONArray) jsonMapper.map((CharSequence) obj);
return (JSONArray) mapper.map((CharSequence) obj);
}
return jsonMapper.mapArray(obj);
return mapper.mapArray(obj);
}
/**
@ -156,6 +257,7 @@ public class JSONFactory {
* @return JSONJSONObject or JSONArray
*/
public JSON parse(final Object obj) {
final JSONMapper mapper = this.getMapper();
if (obj instanceof CharSequence) {
return mapper.map((CharSequence) obj);
}
@ -174,7 +276,7 @@ public class JSONFactory {
* @return Bean对象
*/
public <T> T toBean(final JSON json, final Type type) {
return mapper.toBean(json, type);
return getMapper().toBean(json, type);
}
// endregion

View File

@ -25,7 +25,6 @@ import org.dromara.hutool.core.map.MapUtil;
import org.dromara.hutool.core.map.MapWrapper;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.core.util.ObjUtil;
import org.dromara.hutool.json.serializer.JSONMapper;
import org.dromara.hutool.json.writer.JSONWriter;
import java.util.Arrays;
@ -49,17 +48,23 @@ public class JSONObject extends MapWrapper<String, JSON> implements JSON, JSONGe
*/
public static final int DEFAULT_CAPACITY = MapUtil.DEFAULT_INITIAL_CAPACITY;
/**
* 配置项
*/
private final JSONConfig config;
private final JSONMapper mapper;
private final JSONFactory factory;
// region ----- 构造
/**
* 构造初始容量为 {@link #DEFAULT_CAPACITY}KEY有序
*/
public JSONObject() {
this(JSONConfig.of());
this(DEFAULT_CAPACITY);
}
/**
* 构造
*
* @param capacity 初始大小
*/
public JSONObject(final int capacity) {
this(capacity, JSONFactory.getInstance());
}
/**
@ -79,14 +84,24 @@ public class JSONObject extends MapWrapper<String, JSON> implements JSON, JSONGe
* @param config JSON配置项{@code null}则使用默认配置
*/
public JSONObject(final int capacity, final JSONConfig config) {
super(InternalJSONUtil.createRawMap(capacity, config));
this.config = ObjUtil.defaultIfNull(config, JSONConfig::of);
this.mapper = JSONMapper.of(config, null);
this(capacity, JSONFactory.of(config, null));
}
/**
* 构造
*
* @param capacity 初始大小
* @param factory JSON工厂类
*/
public JSONObject(final int capacity, final JSONFactory factory) {
super(InternalJSONUtil.createRawMap(capacity, factory));
this.factory = factory;
}
// endregion
@Override
public JSONConfig config() {
return this.config;
return this.factory.getConfig();
}
@Override
@ -174,7 +189,7 @@ public class JSONObject extends MapWrapper<String, JSON> implements JSON, JSONGe
} else if (object instanceof JSONArray) {
((JSONArray) object).set(value);
} else {
this.set(key, JSONUtil.ofArray(this.config).set(object).set(value));
this.set(key, factory.ofArray().set(object).set(value));
}
return this;
}
@ -220,7 +235,7 @@ public class JSONObject extends MapWrapper<String, JSON> implements JSON, JSONGe
* @throws JSONException 值是无穷数字抛出此异常
*/
public JSONObject set(final String key, final Object value) throws JSONException {
this.put(key, this.mapper.map(value));
this.put(key, factory.getMapper().map(value));
return this;
}
@ -238,11 +253,11 @@ public class JSONObject extends MapWrapper<String, JSON> implements JSON, JSONGe
return null;
}
final boolean ignoreNullValue = this.config.isIgnoreNullValue();
final boolean ignoreNullValue = config().isIgnoreNullValue();
if (null == value && ignoreNullValue) {
// 忽略值模式下如果值为空清除key
return this.remove(key);
} else if (this.config.isCheckDuplicate() && containsKey(key)) {
} else if (config().isCheckDuplicate() && containsKey(key)) {
throw new JSONException("Duplicate key \"{}\"", key);
}
return super.put(key, value);

View File

@ -70,11 +70,8 @@ public class JSONPrimitive implements Wrapper<Object>, JSON {
|| String.class == type;
}
private final JSONFactory factory;
private Object value;
/**
* 配置项
*/
private JSONConfig config;
/**
* 构造
@ -83,8 +80,18 @@ public class JSONPrimitive implements Wrapper<Object>, JSON {
* @param config 配置项
*/
public JSONPrimitive(final Object value, final JSONConfig config) {
this(value, JSONFactory.of(config, null));
}
/**
* 构造
*
* @param value
* @param factory 配置项
*/
public JSONPrimitive(final Object value, final JSONFactory factory) {
this.value = Assert.notNull(value);
this.config = config;
this.factory = factory;
}
/**
@ -114,18 +121,7 @@ public class JSONPrimitive implements Wrapper<Object>, JSON {
@Override
public JSONConfig config() {
return this.config;
}
/**
* 设置配置项
*
* @param config 配置项
* @return this
*/
JSONPrimitive setConfig(final JSONConfig config) {
this.config = config;
return this;
return this.factory.getConfig();
}
/**
@ -205,13 +201,6 @@ public class JSONPrimitive implements Wrapper<Object>, JSON {
}
}
@Override
public String toString() {
final JSONWriter jsonWriter = JSONWriter.of(new StringBuilder(), 0, 0, this.config);
write(jsonWriter);
return jsonWriter.toString();
}
/**
* 写出数字根据{@link JSONConfig#isStripTrailingZeros()} 配置不同写出不同数字<br>
* 主要针对Double型是否去掉小数点后多余的0<br>

View File

@ -24,11 +24,9 @@ import org.dromara.hutool.core.reflect.TypeReference;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.core.util.ObjUtil;
import org.dromara.hutool.json.support.JSONStrFormatter;
import org.dromara.hutool.json.writer.JSONWriter;
import org.dromara.hutool.json.xml.JSONXMLUtil;
import java.io.File;
import java.io.Writer;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.util.List;
@ -49,7 +47,7 @@ public class JSONUtil {
* @return JSONObject
*/
public static JSONObject ofObj() {
return new JSONObject();
return JSONFactory.getInstance().ofObj();
}
/**
@ -60,7 +58,7 @@ public class JSONUtil {
* @since 5.2.5
*/
public static JSONObject ofObj(final JSONConfig config) {
return new JSONObject(config);
return JSONFactory.of(config, null).ofObj();
}
/**
@ -69,7 +67,7 @@ public class JSONUtil {
* @return JSONArray
*/
public static JSONArray ofArray() {
return new JSONArray();
return JSONFactory.getInstance().ofArray();
}
/**
@ -80,7 +78,7 @@ public class JSONUtil {
* @since 5.2.5
*/
public static JSONArray ofArray(final JSONConfig config) {
return new JSONArray(config);
return JSONFactory.of(config, null).ofArray();
}
/**
@ -117,7 +115,7 @@ public class JSONUtil {
* @since 6.0.0
*/
public static JSONPrimitive ofPrimitive(final Object value, final JSONConfig config) {
return new JSONPrimitive(value, config);
return JSONFactory.of(config, null).ofPrimitive(value);
}
// endregion
@ -335,13 +333,14 @@ public class JSONUtil {
* 转换为JSON字符串并写出到writer
*
* @param obj 被转为JSON的对象
* @param writer Writer
* @param appendable {@link Appendable}
* @since 5.3.3
*/
public static void toJsonStr(final Object obj, final Writer writer) {
if (null != obj) {
parse(obj).write(JSONWriter.of(writer, 0, 0, null));
}
public static void toJsonStr(final Object obj, final Appendable appendable) {
Assert.notNull(appendable);
final JSONFactory jsonFactory = JSONFactory.of(null, null);
final JSON json = jsonFactory.parse(obj);
json.write(jsonFactory.ofWriter(appendable, 0));
}
/**

View File

@ -16,11 +16,10 @@
package org.dromara.hutool.json.engine;
import org.dromara.hutool.core.util.ObjUtil;
import org.dromara.hutool.json.JSON;
import org.dromara.hutool.json.JSONConfig;
import org.dromara.hutool.json.JSONFactory;
import org.dromara.hutool.json.JSONUtil;
import org.dromara.hutool.json.writer.JSONWriter;
import java.io.Reader;
import java.io.Writer;
@ -34,34 +33,30 @@ import java.lang.reflect.Type;
*/
public class HutoolJSONEngine extends AbstractJSONEngine {
private JSONConfig hutoolSJONConfig;
private JSONFactory jsonFactory;
@Override
public void serialize(final Object bean, final Writer writer) {
initEngine();
final JSON json = JSONUtil.parse(bean, this.hutoolSJONConfig);
final JSONWriter jsonWriter = JSONWriter.of(writer,
ObjUtil.defaultIfNull(this.config, JSONEngineConfig::isPrettyPrint, false) ? 2 : 0,
0,
this.hutoolSJONConfig);
json.write(jsonWriter);
final JSON json = jsonFactory.parse(bean);
json.write(jsonFactory.ofWriter(writer, this.config.isPrettyPrint()));
}
@Override
public <T> T deserialize(final Reader reader, final Object type) {
initEngine();
final JSON json = JSONUtil.parse(reader, this.hutoolSJONConfig);
final JSON json = jsonFactory.parse(reader);
return json.toBean((Type) type);
}
@Override
protected void reset() {
hutoolSJONConfig = null;
jsonFactory = null;
}
@Override
protected void initEngine() {
if(null != hutoolSJONConfig){
if(null != jsonFactory){
return;
}
@ -72,6 +67,6 @@ public class HutoolJSONEngine extends AbstractJSONEngine {
hutoolSJONConfig.setIgnoreNullValue(this.config.isIgnoreNullValue());
}
this.hutoolSJONConfig = hutoolSJONConfig;
this.jsonFactory = JSONFactory.of(hutoolSJONConfig, null);
}
}

View File

@ -17,12 +17,10 @@
package org.dromara.hutool.json.serializer;
import org.dromara.hutool.core.lang.Opt;
import org.dromara.hutool.core.lang.mutable.MutableEntry;
import org.dromara.hutool.core.reflect.TypeReference;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.core.util.ObjUtil;
import org.dromara.hutool.json.*;
import org.dromara.hutool.json.reader.JSONParser;
import org.dromara.hutool.json.reader.JSONTokener;
import org.dromara.hutool.json.xml.JSONXMLParser;
import org.dromara.hutool.json.xml.ParseConfig;
@ -31,7 +29,6 @@ import java.io.Serializable;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.Optional;
import java.util.function.Predicate;
/**
* 对象和JSON值映射器用于Java对象和JSON对象互转<br>
@ -53,27 +50,23 @@ public class JSONMapper implements Serializable {
/**
* 创建JSONMapper
*
* @param jsonConfig 来源对象
* @param predicate 键值对过滤编辑器可以通过实现此接口完成解析前对键值对的过滤和修改操作{@link Predicate#test(Object)}{@code true}保留
* @param factory {@link JSONFactory}
* @return ObjectMapper
*/
public static JSONMapper of(final JSONConfig jsonConfig, final Predicate<MutableEntry<Object, Object>> predicate) {
return new JSONMapper(jsonConfig, predicate);
public static JSONMapper of(final JSONFactory factory) {
return new JSONMapper(factory);
}
private final JSONConfig jsonConfig;
private final Predicate<MutableEntry<Object, Object>> predicate;
private final JSONFactory factory;
private TypeAdapterManager typeAdapterManager;
/**
* 构造
*
* @param jsonConfig JSON配置
* @param predicate 键值对过滤编辑器可以通过实现此接口完成解析前对键值对的过滤和修改操作{@link Predicate#test(Object)}{@code true}保留
* @param factory {@link JSONFactory}
*/
public JSONMapper(final JSONConfig jsonConfig, final Predicate<MutableEntry<Object, Object>> predicate) {
this.jsonConfig = ObjUtil.defaultIfNull(jsonConfig, JSONConfig::of);
this.predicate = predicate;
public JSONMapper(final JSONFactory factory) {
this.factory = factory;
}
/**
@ -126,7 +119,7 @@ public class JSONMapper implements Serializable {
if (null == deserializer) {
deserializer = TypeAdapterManager.getInstance().getDeserializer(json, type);
}
final boolean ignoreError = ObjUtil.defaultIfNull(this.jsonConfig, JSONConfig::isIgnoreError, false);
final boolean ignoreError = ObjUtil.defaultIfNull(this.factory.getConfig(), JSONConfig::isIgnoreError, false);
if (null == deserializer) {
if (ignoreError) {
return null;
@ -152,7 +145,7 @@ public class JSONMapper implements Serializable {
* @return JSONArray
*/
public JSONArray mapFromJSONObject(final JSONObject jsonObject) {
final JSONArray array = JSONUtil.ofArray(jsonConfig);
final JSONArray array = factory.ofArray();
for (final Map.Entry<String, JSON> entry : jsonObject) {
array.set(entry);
}
@ -168,15 +161,15 @@ public class JSONMapper implements Serializable {
*/
public JSON map(final CharSequence source) {
final String jsonStr = StrUtil.trim(source);
if(StrUtil.isEmpty(jsonStr)){
if (StrUtil.isEmpty(jsonStr)) {
// https://www.rfc-editor.org/rfc/rfc8259#section-7
// 未被包装的空串理解为null
return null;
}
if (StrUtil.startWith(jsonStr, '<')) {
// 可能为XML
final JSONObject jsonObject = JSONUtil.ofObj(jsonConfig);
JSONXMLParser.of(ParseConfig.of(), this.predicate).parseJSONObject(jsonStr, jsonObject);
final JSONObject jsonObject = this.factory.ofObj();
JSONXMLParser.of(ParseConfig.of(), this.factory.getPredicate()).parseJSONObject(jsonStr, jsonObject);
return jsonObject;
}
@ -212,7 +205,7 @@ public class JSONMapper implements Serializable {
* @return 映射后的值null表示此值需被忽略
*/
public JSONObject mapObj(final Object obj) {
return mapTo(obj, JSONUtil.ofObj(jsonConfig));
return mapTo(obj, factory.ofObj());
}
/**
@ -226,7 +219,7 @@ public class JSONMapper implements Serializable {
* @return 映射后的值null表示此值需被忽略
*/
public JSONArray mapArray(final Object obj) {
return mapTo(obj, JSONUtil.ofArray(jsonConfig));
return mapTo(obj, factory.ofArray());
}
/**
@ -283,7 +276,7 @@ public class JSONMapper implements Serializable {
if (null == serializer) {
serializer = TypeAdapterManager.getInstance().getSerializer(obj, clazz);
}
final boolean ignoreError = ObjUtil.defaultIfNull(this.jsonConfig, JSONConfig::isIgnoreError, false);
final boolean ignoreError = ObjUtil.defaultIfNull(this.factory.getConfig(), JSONConfig::isIgnoreError, false);
if (null == serializer) {
if (ignoreError) {
return null;
@ -293,7 +286,7 @@ public class JSONMapper implements Serializable {
final JSON result;
try {
result = serializer.serialize(obj, new SimpleJSONContext(json, this.jsonConfig));
result = serializer.serialize(obj, new SimpleJSONContext(json, this.factory.getConfig()));
} catch (final Exception e) {
if (ignoreError) {
return null;
@ -301,11 +294,11 @@ public class JSONMapper implements Serializable {
throw e;
}
if(null == json || result.getClass() == json.getClass()){
if (null == json || result.getClass() == json.getClass()) {
return (T) result;
}
if(ignoreError){
if (ignoreError) {
return null;
}
throw new JSONException("JSON type not match, expect: {}, actual: {}",
@ -319,6 +312,6 @@ public class JSONMapper implements Serializable {
* @return JSON
*/
private JSON mapFromTokener(final JSONTokener tokener) {
return JSONParser.of(tokener, jsonConfig).setPredicate(this.predicate).parse();
return this.factory.ofParser(tokener).parse();
}
}

View File

@ -45,13 +45,33 @@ public class JSONWriter implements Appendable, Flushable, Closeable {
*
* @param appendable {@link Appendable}
* @param indentFactor 缩进因子定义每一级别增加的缩进量
* @param indent 本级别缩进量
* @param config JSON选项
* @param predicate predicate 字段过滤器
* @return JSONWriter
*/
public static JSONWriter of(final Appendable appendable, final int indentFactor, final int indent,
final JSONConfig config) {
return new JSONWriter(appendable, indentFactor, indent, config);
public static JSONWriter of(final Appendable appendable,
final int indentFactor,
final JSONConfig config,
final Predicate<MutableEntry<Object, Object>> predicate) {
return of(appendable, indentFactor, 0, config, predicate);
}
/**
* 创建JSONWriter
*
* @param appendable {@link Appendable}
* @param indentFactor 缩进因子定义每一级别增加的缩进量
* @param indent 本级别缩进量
* @param config JSON选项
* @param predicate predicate 字段过滤器
* @return JSONWriter
*/
public static JSONWriter of(final Appendable appendable,
final int indentFactor,
final int indent,
final JSONConfig config,
final Predicate<MutableEntry<Object, Object>> predicate) {
return new JSONWriter(appendable, indentFactor, indent, config, predicate);
}
/**
@ -70,7 +90,7 @@ public class JSONWriter implements Appendable, Flushable, Closeable {
/**
* 键值对过滤器用于修改键值对
*/
private Predicate<MutableEntry<Object, Object>> predicate;
private final Predicate<MutableEntry<Object, Object>> predicate;
/**
@ -89,23 +109,18 @@ public class JSONWriter implements Appendable, Flushable, Closeable {
* @param indentFactor 缩进因子定义每一级别增加的缩进量
* @param indent 本级别缩进量
* @param config JSON选项
* @param predicate 字段过滤器
*/
public JSONWriter(final Appendable appendable, final int indentFactor, final int indent, final JSONConfig config) {
public JSONWriter(final Appendable appendable,
final int indentFactor,
final int indent,
final JSONConfig config,
final Predicate<MutableEntry<Object, Object>> predicate) {
this.appendable = appendable;
this.indentFactor = indentFactor;
this.indent = indent;
this.config = ObjUtil.defaultIfNull(config, JSONConfig::of);
}
/**
* 设置键值对过滤器用于修改键值对
*
* @param predicate 键值对过滤器用于修改键值对
* @return this
*/
public JSONWriter setPredicate(final Predicate<MutableEntry<Object, Object>> predicate) {
this.predicate = predicate;
return this;
}
/**

View File

@ -17,7 +17,6 @@
package org.dromara.hutool.json;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.json.serializer.JSONMapper;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@ -27,11 +26,11 @@ public class IssueI9DX5HTest {
@Test
void xmlToJSONTest() {
final String xml = "<GoodMsg>你好</GoodMsg>";
final JSONMapper mapper = JSONMapper.of(JSONConfig.of(), entry -> {
final JSONFactory factory = JSONFactory.of(JSONConfig.of(), entry -> {
entry.setKey(StrUtil.toUnderlineCase((CharSequence) entry.getKey()));
return true;
});
final JSONObject jsonObject = (JSONObject) mapper.map(xml);
final JSONObject jsonObject = (JSONObject) factory.parse(xml);
Assertions.assertEquals("{\"good_msg\":\"你好\"}", jsonObject.toString());
}

View File

@ -28,7 +28,6 @@ import org.dromara.hutool.log.AbstractLog;
* <a href="http://logging.apache.org/log4j/2.x/index.html">Apache Log4J 2</a> log.<br>
*
* @author Looly
*
*/
public class Log4j2Log extends AbstractLog {
private static final long serialVersionUID = -6843151523380063975L;
@ -36,18 +35,33 @@ public class Log4j2Log extends AbstractLog {
private final transient Logger logger;
// ------------------------------------------------------------------------- Constructor
public Log4j2Log(final Logger logger) {
this.logger = logger;
}
/**
* 构造
*
* @param clazz 日志标识
*/
public Log4j2Log(final Class<?> clazz) {
this(LogManager.getLogger(clazz));
}
/**
* 构造
*
* @param name 日志标识
*/
public Log4j2Log(final String name) {
this(LogManager.getLogger(name));
}
/**
* 构造
*
* @param logger 日志实现
*/
public Log4j2Log(final Logger logger) {
this.logger = logger;
}
@Override
public String getName() {
return logger.getName();

View File

@ -39,19 +39,32 @@ public class Slf4jLog extends AbstractLog {
private final boolean isLocationAwareLogger;
// ------------------------------------------------------------------------- Constructor
public Slf4jLog(final Logger logger) {
this.logger = logger;
this.isLocationAwareLogger = (logger instanceof LocationAwareLogger);
}
/**
* 构造
* @param clazz 日志所在类用于获取打印时的类名
*/
public Slf4jLog(final Class<?> clazz) {
this(getSlf4jLogger(clazz));
}
/**
* 构造
* @param name 打印的类名
*/
public Slf4jLog(final String name) {
this(LoggerFactory.getLogger(name));
}
/**
* 构造
* @param logger {@link Logger} 日志实现
*/
public Slf4jLog(final Logger logger) {
this.logger = logger;
this.isLocationAwareLogger = (logger instanceof LocationAwareLogger);
}
@Override
public String getName() {
return logger.getName();