This commit is contained in:
Looly 2024-10-01 11:00:05 +08:00
parent 06ada31d88
commit 64a04fdfd1
10 changed files with 133 additions and 144 deletions

View File

@ -117,7 +117,7 @@ public final class InternalJSONUtil {
.setIgnoreError(config.isIgnoreError())
.setIgnoreNullValue(config.isIgnoreNullValue())
.setTransientSupport(config.isTransientSupport())
.setConverter((targetType, value) -> mapper.map(value));
.setConverter((targetType, value) -> mapper.toJSON(value));
}
/**

View File

@ -44,6 +44,22 @@ public interface JSON extends Serializable {
*/
JSONFactory getFactory();
/**
* JSON大小对于JSONObject是键值对的多少JSONArray则是元素的个数JSON原始数据为1
*
* @return 大小
*/
int size();
/**
* 将JSON内容写入Writer<br>
* Warning: This method assumes that the data structure is acyclical.
*
* @param writer writer
* @throws JSONException JSON相关异常
*/
void write(JSONWriter writer) throws JSONException;
/**
* 获取JSON配置
*
@ -54,13 +70,6 @@ public interface JSON extends Serializable {
return getFactory().getConfig();
}
/**
* JSON大小对于JSONObject是键值对的多少JSONArray则是元素的个数JSON原始数据为1
*
* @return 大小
*/
int size();
/**
* 判断JSON是否为空即大小为0
*
@ -244,15 +253,6 @@ public interface JSON extends Serializable {
return jsonWriter.toString();
}
/**
* 将JSON内容写入Writer<br>
* Warning: This method assumes that the data structure is acyclical.
*
* @param writer writer
* @throws JSONException JSON相关异常
*/
void write(JSONWriter writer) throws JSONException;
/**
* 转为实体类对象
*

View File

@ -120,7 +120,7 @@ public class JSONArray extends ListWrapper<JSON> implements JSON, JSONGetter<Int
* @return this.
*/
public JSONArray addObj(final Object value) {
this.add(this.factory.getMapper().map(value));
this.add(this.factory.getMapper().toJSON(value));
return this;
}
@ -171,7 +171,7 @@ public class JSONArray extends ListWrapper<JSON> implements JSON, JSONGetter<Int
* @return this
*/
public JSONArray setObj(final int index, final Object element) {
set(index, this.factory.getMapper().map(element));
set(index, this.factory.getMapper().toJSON(element));
return this;
}

View File

@ -273,11 +273,7 @@ public class JSONFactory {
* @return JSONObject
*/
public JSONObject parseObj(final Object obj) {
final JSONMapper mapper = getMapper();
if (obj instanceof CharSequence) {
return (JSONObject) mapper.map((CharSequence) obj);
}
return mapper.mapObj(obj);
return getMapper().toJSONObject(obj);
}
/**
@ -292,11 +288,7 @@ public class JSONFactory {
* @return JSONArray
*/
public JSONArray parseArray(final Object obj) {
final JSONMapper mapper = getMapper();
if (obj instanceof CharSequence) {
return (JSONArray) mapper.map((CharSequence) obj);
}
return mapper.mapArray(obj);
return getMapper().toJSONArray(obj);
}
/**
@ -314,9 +306,9 @@ public class JSONFactory {
public JSON parse(final Object obj) {
final JSONMapper mapper = this.getMapper();
if (obj instanceof CharSequence) {
return mapper.map((CharSequence) obj);
return mapper.toJSON((CharSequence) obj);
}
return mapper.map(obj);
return mapper.toJSON(obj);
}
// endregion

View File

@ -219,9 +219,7 @@ public class JSONObject extends MapWrapper<String, JSON> implements JSON, JSONGe
*/
public JSONObject putAllObj(final Map<?, ?> map) {
if(MapUtil.isNotEmpty(map)){
for (final Entry<?, ?> entry : map.entrySet()) {
this.putObj(StrUtil.toStringOrNull(entry.getKey()), entry.getValue());
}
map.forEach((key, value) -> putObj(StrUtil.toStringOrNull(key), value));
}
return this;
}
@ -235,7 +233,7 @@ public class JSONObject extends MapWrapper<String, JSON> implements JSON, JSONGe
* @throws JSONException 值是无穷数字抛出此异常
*/
public JSONObject putObj(final String key, final Object value) throws JSONException {
this.put(key, factory.getMapper().map(value));
this.put(key, factory.getMapper().toJSON(value));
return this;
}

View File

@ -18,23 +18,18 @@ package org.dromara.hutool.json.serializer;
import org.dromara.hutool.core.lang.Opt;
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.JSONTokener;
import org.dromara.hutool.json.serializer.impl.DefaultDeserializer;
import org.dromara.hutool.json.xml.JSONXMLParser;
import org.dromara.hutool.json.xml.ParseConfig;
import java.io.Serializable;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.Optional;
/**
* 对象和JSON值映射器用于Java对象和JSON对象互转<br>
* <ul>
* <li>Java对象转JSON{@link #map(Object)}</li>
* <li>Java对象转JSON{@link #toJSON(Object)}</li>
* <li>JSON转Java对象{@link #toBean(JSON, Type)}</li>
* </ul>
* <p>
@ -70,6 +65,8 @@ public class JSONMapper implements Serializable {
this.factory = factory;
}
// region ----- typeAdapterManager
/**
* 获取自定义类型转换器用于将自定义类型转换为JSONObject
*
@ -114,6 +111,7 @@ public class JSONMapper implements Serializable {
initTypeAdapterManager().register(typeAdapter);
return this;
}
//endregion
/**
* 转为实体类对象
@ -129,68 +127,18 @@ public class JSONMapper implements Serializable {
type = ((TypeReference<?>) type).getType();
}
JSONDeserializer<Object> deserializer = null;
// 自定义反序列化
if (null != this.typeAdapterManager) {
deserializer = this.typeAdapterManager.getDeserializer(json, type);
}
// 全局自定义反序列化
if (null == deserializer) {
deserializer = TypeAdapterManager.getInstance().getDeserializer(json, type);
}
final boolean ignoreError = ObjUtil.defaultIfNull(this.factory.getConfig(), JSONConfig::isIgnoreError, false);
if (null == deserializer) {
deserializer = DefaultDeserializer.INSTANCE;
}
final JSONDeserializer<Object> deserializer = getDeserializer(json, type);
try {
return (T) deserializer.deserialize(json, type);
} catch (final Exception e) {
if (ignoreError) {
if (ObjUtil.defaultIfNull(this.factory.getConfig(), JSONConfig::isIgnoreError, false)) {
return null;
}
throw e;
}
}
/**
* 将JSONObject转换为JSONArrayM<br>
* 在普通的Serializer中JSONObject会被直接返回如果想转为JSONArray
*
* @param jsonObject JSONObject
* @return JSONArray
*/
public JSONArray mapFromJSONObject(final JSONObject jsonObject) {
final JSONArray array = factory.ofArray();
for (final Map.Entry<String, JSON> entry : jsonObject) {
array.addObj(entry);
}
return array;
}
/**
* 解析JSON字符串或XML字符串为JSON结构<br>
* 在普通的Serializer中字符串会被作为普通字符串转为{@link JSONPrimitive},此处做区分
*
* @param source JSON字符串或XML字符串
* @return JSON对象
*/
public JSON map(final CharSequence source) {
final String jsonStr = StrUtil.trim(source);
if (StrUtil.isEmpty(jsonStr)) {
// https://www.rfc-editor.org/rfc/rfc8259#section-7
// 未被包装的空串理解为null
return null;
}
if (StrUtil.startWith(jsonStr, '<')) {
// 可能为XML
final JSONObject jsonObject = this.factory.ofObj();
JSONXMLParser.of(ParseConfig.of(), this.factory.getPredicate()).parseJSONObject(jsonStr, jsonObject);
return jsonObject;
}
return mapFromTokener(new JSONTokener(source));
}
// region ----- toJSON
/**
* 在需要的时候转换映射对象<br>
@ -201,12 +149,11 @@ public class JSONMapper implements Serializable {
* <li>standard property (Double, String, et al) = 原对象</li>
* <li>其它 = 尝试包装为JSONObject否则返回{@code null}</li>
* </ul>
* 注意此方法不支持JSON字符串的解析解析请用{@link #map(CharSequence)}
*
* @param obj 被映射的对象
* @return 映射后的值null表示此值需被忽略
*/
public JSON map(final Object obj) {
public JSON toJSON(final Object obj) {
return mapTo(obj, null);
}
@ -221,7 +168,7 @@ public class JSONMapper implements Serializable {
* @param obj 被映射的对象
* @return 映射后的值null表示此值需被忽略
*/
public JSONObject mapObj(final Object obj) {
public JSONObject toJSONObject(final Object obj) {
return mapTo(obj, factory.ofObj());
}
@ -235,9 +182,10 @@ public class JSONMapper implements Serializable {
* @param obj 被映射的对象
* @return 映射后的值null表示此值需被忽略
*/
public JSONArray mapArray(final Object obj) {
public JSONArray toJSONArray(final Object obj) {
return mapTo(obj, factory.ofArray());
}
// endregion
/**
* 在需要的时候转换映射对象<br>
@ -272,6 +220,15 @@ public class JSONMapper implements Serializable {
}
}
// JSONPrimitive对象
// 考虑性能问题默认原始类型对象直接包装为JSONPrimitive不再查找TypeAdapter
// 如果原始类型想转为其他JSON类型依旧可以查找TypeAdapter
if (JSONPrimitive.isTypeForJSONPrimitive(obj)) {
if (null == json || json instanceof JSONPrimitive) {
return (T) factory.ofPrimitive(obj);
}
}
// JSON对象如果与预期结果类型一致则直接返回
if (obj instanceof JSON) {
if (null != json) {
@ -283,16 +240,7 @@ public class JSONMapper implements Serializable {
}
}
final Class<?> clazz = obj.getClass();
JSONSerializer<Object> serializer = null;
// 自定义序列化
if (null != this.typeAdapterManager) {
serializer = this.typeAdapterManager.getSerializer(obj, clazz);
}
// 全局自定义序列化
if (null == serializer) {
serializer = TypeAdapterManager.getInstance().getSerializer(obj, clazz);
}
final JSONSerializer<Object> serializer = getSerializer(obj, obj.getClass());
final boolean ignoreError = ObjUtil.defaultIfNull(this.factory.getConfig(), JSONConfig::isIgnoreError, false);
if (null == serializer) {
if (ignoreError) {
@ -322,16 +270,6 @@ public class JSONMapper implements Serializable {
json.getClass().getName(), result.getClass().getName());
}
/**
* {@link JSONTokener} 中读取JSON字符串并转换为JSON
*
* @param tokener {@link JSONTokener}
* @return JSON
*/
private JSON mapFromTokener(final JSONTokener tokener) {
return this.factory.ofParser(tokener).parse();
}
/**
* 初始化类型转换器管理器如果尚未初始化则初始化否则直接返回
*
@ -347,4 +285,48 @@ public class JSONMapper implements Serializable {
}
return this.typeAdapterManager;
}
/**
* 获取JSON对象对应的序列化器先查找局部自定义如果没有则查找全局自定义
*
* @param obj 对象
* @param clazz 对象类型
* @return {@link JSONSerializer}
*/
private JSONSerializer<Object> getSerializer(final Object obj, final Class<?> clazz) {
JSONSerializer<Object> serializer = null;
// 自定义序列化
if (null != this.typeAdapterManager) {
serializer = this.typeAdapterManager.getSerializer(obj, clazz);
}
// 全局自定义序列化
if (null == serializer) {
serializer = TypeAdapterManager.getInstance().getSerializer(obj, clazz);
}
return serializer;
}
/**
* 获取JSON对象对应的反序列化器先查找局部自定义如果没有则查找全局自定义如果都没有则使用默认反序列化器
*
* @param json JSON对象
* @param type 反序列化目标类型
* @return {@link JSONDeserializer}
*/
private JSONDeserializer<Object> getDeserializer(final JSON json, final Type type) {
JSONDeserializer<Object> deserializer = null;
// 自定义反序列化
if (null != this.typeAdapterManager) {
deserializer = this.typeAdapterManager.getDeserializer(json, type);
}
// 全局自定义反序列化
if (null == deserializer) {
deserializer = TypeAdapterManager.getInstance().getDeserializer(json, type);
}
// 默认反序列化
if (null == deserializer) {
deserializer = DefaultDeserializer.INSTANCE;
}
return deserializer;
}
}

View File

@ -290,6 +290,7 @@ public class TypeAdapterManager {
manager.register(ResourceBundleSerializer.INSTANCE);
// 自定义反序列化器
manager.register(JSONPrimitiveDeserializer.INSTANCE);
manager.register(KBeanDeserializer.INSTANCE);
manager.register(RecordDeserializer.INSTANCE);
manager.register(Triple.class, TripleDeserializer.INSTANCE);
@ -297,7 +298,6 @@ public class TypeAdapterManager {
manager.register(Tuple.class, TupleDeserializer.INSTANCE);
// 自定义类型适配器
manager.register(JSONPrimitiveTypeAdapter.INSTANCE);
manager.register(CharSequenceTypeAdapter.INSTANCE);
manager.register(DateTypeAdapter.INSTANCE);
manager.register(CalendarTypeAdapter.INSTANCE);

View File

@ -19,6 +19,7 @@ package org.dromara.hutool.json.serializer.impl;
import org.dromara.hutool.core.reflect.TypeUtil;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.json.JSON;
import org.dromara.hutool.json.JSONFactory;
import org.dromara.hutool.json.JSONObject;
import org.dromara.hutool.json.JSONPrimitive;
import org.dromara.hutool.json.reader.JSONTokener;
@ -31,7 +32,13 @@ import org.dromara.hutool.json.xml.ParseConfig;
import java.lang.reflect.Type;
/**
* CharSequence类型适配器用于处理未匹配的JSON类型
* {@link CharSequence}类型适配器主要用于
* <ul>
* <li>序列化(serialize)按照给定类型解析JSON或XML字符串为{@link JSON}</li>
* <li>反序列化(deserialize)如果为原始值返回原始值并调用toString方法其他JSON对象直接转为JSON字符换</li>
* </ul>
*
* {@link CharSequence}适配器主要解决在JSON的get调用时如果用户指定为字符串类型转换问题
*
* @author looly
* @since 6.0.0
@ -55,7 +62,22 @@ public class CharSequenceTypeAdapter implements MatcherJSONSerializer<CharSequen
@Override
public JSON serialize(final CharSequence bean, final JSONContext context) {
// null 检查
final String jsonStr = StrUtil.trim(bean);
if (StrUtil.isEmpty(jsonStr)) {
// https://www.rfc-editor.org/rfc/rfc8259#section-7
// 未被包装的空串理解为null
return null;
}
final JSON contextJson = context.getContextJson();
// 如果指定序列化为JSONPrimitive则直接返回原始值
if (contextJson instanceof JSONPrimitive) {
return context.getOrCreatePrimitive(bean);
}
// 按照XML解析
if (StrUtil.startWith(jsonStr, '<')) {
// 可能为XML
final JSONObject jsonObject = context.getOrCreateObj();
@ -63,14 +85,26 @@ public class CharSequenceTypeAdapter implements MatcherJSONSerializer<CharSequen
return jsonObject;
}
return context.getFactory().ofParser(new JSONTokener(jsonStr)).parse();
// 按照JSON字符串解析
return parse(new JSONTokener(jsonStr), context.getFactory());
}
@Override
public CharSequence deserialize(final JSON json, final Type deserializeType) {
if(json instanceof JSONPrimitive){
if (json instanceof JSONPrimitive) {
return ((JSONPrimitive) json).getValue().toString();
}
return json.toString();
}
/**
* {@link JSONTokener} 中读取JSON字符串并解析为JSON
*
* @param tokener {@link JSONTokener}
* @param factory JSON工厂
* @return JSON
*/
public static JSON parse(final JSONTokener tokener, final JSONFactory factory) {
return factory.ofParser(tokener).parse();
}
}

View File

@ -22,45 +22,28 @@ import org.dromara.hutool.core.util.ObjUtil;
import org.dromara.hutool.json.JSON;
import org.dromara.hutool.json.JSONConfig;
import org.dromara.hutool.json.JSONPrimitive;
import org.dromara.hutool.json.serializer.JSONContext;
import org.dromara.hutool.json.serializer.MatcherJSONDeserializer;
import org.dromara.hutool.json.serializer.MatcherJSONSerializer;
import java.lang.reflect.Type;
/**
* {@link JSONPrimitive}相关类型适配器用于处理数字类型的序列化和反序列化
* {@link JSONPrimitive}相关类型反序列化
*
* @author Looly
* @since 6.0.0
*/
public class JSONPrimitiveTypeAdapter implements MatcherJSONSerializer<Object>, MatcherJSONDeserializer<Object> {
public class JSONPrimitiveDeserializer implements MatcherJSONDeserializer<Object> {
/**
* 单例
*/
public static final JSONPrimitiveTypeAdapter INSTANCE = new JSONPrimitiveTypeAdapter();
@Override
public boolean match(final Object bean, final JSONContext context) {
return JSONPrimitive.isTypeForJSONPrimitive(bean);
}
public static final JSONPrimitiveDeserializer INSTANCE = new JSONPrimitiveDeserializer();
@Override
public boolean match(final JSON json, final Type deserializeType) {
return json instanceof JSONPrimitive && JSONPrimitive.isTypeForJSONPrimitive(TypeUtil.getClass(deserializeType));
}
@Override
public JSON serialize(Object bean, final JSONContext context) {
if(bean instanceof Character){
// 字符按照字符串存储
bean = bean.toString();
}
return context.getOrCreatePrimitive(bean);
}
@Override
public Object deserialize(final JSON json, final Type deserializeType) {
final Object value = json.asJSONPrimitive().getValue();

View File

@ -46,11 +46,11 @@ public class JsonPutJmh {
@Benchmark
public void hutoolJmh() {
testData.forEach(hutoolJSON::putObj);
hutoolJSON.putAllObj(testData);
}
@Benchmark
public void fastJSONJmh() {
testData.forEach(fastJSON::put);
fastJSON.putAll(testData);
}
}