add custom serialize support

This commit is contained in:
Looly
2019-09-03 22:39:50 +08:00
parent b9eaf280cd
commit caa8d6dea7
14 changed files with 415 additions and 50 deletions

View File

@@ -12,6 +12,7 @@
* 【core】 ArrayUtil增加distinct方法 * 【core】 ArrayUtil增加distinct方法
* 【http】 去除log模块依赖Cookie中去除日志提示body方法传入JSON对象废弃未来移除json模块依赖 * 【http】 去除log模块依赖Cookie中去除日志提示body方法传入JSON对象废弃未来移除json模块依赖
* 【extra】 添加MyNLP支持issue#519@Github * 【extra】 添加MyNLP支持issue#519@Github
* 【json】 添加自定义序列化反序列化支持issue#I1052A@Gitee
### Bug修复 ### Bug修复

View File

@@ -44,7 +44,7 @@ public class ClassUtil {
public static <T> Class<T> getClass(T obj) { public static <T> Class<T> getClass(T obj) {
return ((null == obj) ? null : (Class<T>) obj.getClass()); return ((null == obj) ? null : (Class<T>) obj.getClass());
} }
/** /**
* 获得外围类<br> * 获得外围类<br>
* 返回定义此类或匿名类所在的类,如果类本身是在包中定义的,返回{@code null} * 返回定义此类或匿名类所在的类,如果类本身是在包中定义的,返回{@code null}
@@ -56,15 +56,16 @@ public class ClassUtil {
public static Class<?> getEnclosingClass(Class<?> clazz) { public static Class<?> getEnclosingClass(Class<?> clazz) {
return null == clazz ? null : clazz.getEnclosingClass(); return null == clazz ? null : clazz.getEnclosingClass();
} }
/** /**
* 是否为顶层类,既定义在包中的类,而非定义在类中的内部类 * 是否为顶层类,既定义在包中的类,而非定义在类中的内部类
*
* @param clazz 类 * @param clazz 类
* @return 是否为顶层类 * @return 是否为顶层类
* @since 4.5.7 * @since 4.5.7
*/ */
public static boolean isTopLevelClass(Class<?> clazz) { public static boolean isTopLevelClass(Class<?> clazz) {
if(null == clazz) { if (null == clazz) {
return false; return false;
} }
return null == getEnclosingClass(clazz); return null == getEnclosingClass(clazz);
@@ -1018,4 +1019,28 @@ public class ClassUtil {
} }
return values; return values;
} }
/**
* 是否为JDK中定义的类或接口判断依据
*
* <pre>
* 1、以java.、javax.开头的包名
* 2、ClassLoader为null
* </pre>
*
* @param clazz 被检查的类
* @return 是否为JDK中定义的类或接口
* @since 4.6.5
*/
public static boolean isJdkClass(Class<?> clazz) {
final Package objectPackage = clazz.getPackage();
if(null == objectPackage) {
return false;
}
final String objectPackageName = objectPackage.getName();
if (objectPackageName.startsWith("java.") || objectPackageName.startsWith("javax.") || clazz.getClassLoader() == null) {
return true;
}
return false;
}
} }

View File

@@ -16,6 +16,9 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.CharUtil; import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.TypeUtil;
import cn.hutool.json.serialize.GlobalSerializeMapping;
import cn.hutool.json.serialize.JSONSerializer;
/** /**
* JSON数组<br> * JSON数组<br>
@@ -32,7 +35,7 @@ public class JSONArray extends JSONGetter<Integer> implements JSON, List<Object>
private static final long serialVersionUID = 2664900568717612292L; private static final long serialVersionUID = 2664900568717612292L;
/** 默认初始大小 */ /** 默认初始大小 */
private static final int DEFAULT_CAPACITY = 10; public static final int DEFAULT_CAPACITY = 10;
/** 持有原始数据的List */ /** 持有原始数据的List */
private final List<Object> rawList; private final List<Object> rawList;
@@ -59,6 +62,17 @@ public class JSONArray extends JSONGetter<Integer> implements JSON, List<Object>
this(initialCapacity, JSONConfig.create()); this(initialCapacity, JSONConfig.create());
} }
/**
* 构造<br>
* 默认使用{@link ArrayList} 实现
*
* @param config JSON配置项
* @since 4.6.5
*/
public JSONArray(JSONConfig config) {
this(DEFAULT_CAPACITY, config);
}
/** /**
* 构造<br> * 构造<br>
* 默认使用{@link ArrayList} 实现 * 默认使用{@link ArrayList} 实现
@@ -152,11 +166,30 @@ public class JSONArray extends JSONGetter<Integer> implements JSON, List<Object>
* @throws JSONException 非数组或集合 * @throws JSONException 非数组或集合
*/ */
public JSONArray(Object object, boolean ignoreNullValue) throws JSONException { public JSONArray(Object object, boolean ignoreNullValue) throws JSONException {
this(DEFAULT_CAPACITY, JSONConfig.create().setIgnoreNullValue(ignoreNullValue)); this(object, JSONConfig.create().setIgnoreNullValue(ignoreNullValue));
}
/**
* 从对象构造<br>
* 支持以下类型的参数:
*
* <pre>
* 1. 数组
* 2. {@link Iterable}对象
* 3. JSON数组字符串
* </pre>
*
* @param object 数组或集合或JSON数组字符串
* @param jsonConfig JSON选项
* @throws JSONException 非数组或集合
* @since 4.6.5
*/
public JSONArray(Object object, JSONConfig jsonConfig) throws JSONException {
this(DEFAULT_CAPACITY, jsonConfig);
init(object); init(object);
} }
// -------------------------------------------------------------------------------------------------------------------- Constructor start // -------------------------------------------------------------------------------------------------------------------- Constructor start
/** /**
* 设置转为字符串时的日期格式默认为时间戳null值 * 设置转为字符串时的日期格式默认为时间戳null值
* *
@@ -330,7 +363,7 @@ public class JSONArray extends JSONGetter<Integer> implements JSON, List<Object>
@Override @Override
public boolean add(Object e) { public boolean add(Object e) {
return this.rawList.add(JSONUtil.wrap(e, this.config.isIgnoreNullValue())); return this.rawList.add(JSONUtil.wrap(e, this.config));
} }
@Override @Override
@@ -366,7 +399,7 @@ public class JSONArray extends JSONGetter<Integer> implements JSON, List<Object>
} }
final ArrayList<Object> list = new ArrayList<>(c.size()); final ArrayList<Object> list = new ArrayList<>(c.size());
for (Object object : c) { for (Object object : c) {
list.add(JSONUtil.wrap(object, this.config.isIgnoreNullValue())); list.add(JSONUtil.wrap(object, this.config));
} }
return rawList.addAll(index, list); return rawList.addAll(index, list);
} }
@@ -389,17 +422,17 @@ public class JSONArray extends JSONGetter<Integer> implements JSON, List<Object>
@Override @Override
public Object set(int index, Object element) { public Object set(int index, Object element) {
return this.rawList.set(index, JSONUtil.wrap(element, this.config.isIgnoreNullValue())); return this.rawList.set(index, JSONUtil.wrap(element, this.config));
} }
@Override @Override
public void add(int index, Object element) { public void add(int index, Object element) {
if (index < 0) { if (index < 0) {
throw new JSONException("JSONArray[" + index + "] not found."); throw new JSONException("JSONArray[{}] not found.", index);
} }
if (index < this.size()) { if (index < this.size()) {
InternalJSONUtil.testValidity(element); InternalJSONUtil.testValidity(element);
this.rawList.add(index, JSONUtil.wrap(element, this.config.isIgnoreNullValue())); this.rawList.add(index, JSONUtil.wrap(element, this.config));
} else { } else {
while (index != this.size()) { while (index != this.size()) {
this.add(JSONNull.NULL); this.add(JSONNull.NULL);
@@ -455,7 +488,7 @@ public class JSONArray extends JSONGetter<Integer> implements JSON, List<Object>
public <T> List<T> toList(Class<T> elementType) { public <T> List<T> toList(Class<T> elementType) {
return JSONConverter.toList(this, elementType); return JSONConverter.toList(this, elementType);
} }
/** /**
* 转为JSON字符串无缩进 * 转为JSON字符串无缩进
* *
@@ -512,7 +545,7 @@ public class JSONArray extends JSONGetter<Integer> implements JSON, List<Object>
} }
// ------------------------------------------------------------------------------------------------- Private method start // ------------------------------------------------------------------------------------------------- Private method start
/** /**
* 将JSON内容写入Writer * 将JSON内容写入Writer
* *
@@ -528,22 +561,22 @@ public class JSONArray extends JSONGetter<Integer> implements JSON, List<Object>
final boolean isIgnoreNullValue = this.config.isIgnoreNullValue(); final boolean isIgnoreNullValue = this.config.isIgnoreNullValue();
boolean isFirst = true; boolean isFirst = true;
for (Object obj : this.rawList) { for (Object obj : this.rawList) {
if(ObjectUtil.isNull(obj) && isIgnoreNullValue) { if (ObjectUtil.isNull(obj) && isIgnoreNullValue) {
continue; continue;
} }
if (isFirst) { if (isFirst) {
isFirst = false; isFirst = false;
}else { } else {
writer.write(CharUtil.COMMA); writer.write(CharUtil.COMMA);
} }
if (indentFactor > 0) { if (indentFactor > 0) {
writer.write(CharUtil.LF); writer.write(CharUtil.LF);
} }
InternalJSONUtil.indent(writer, newindent); InternalJSONUtil.indent(writer, newindent);
InternalJSONUtil.writeValue(writer, obj, indentFactor, newindent, this.config); InternalJSONUtil.writeValue(writer, obj, indentFactor, newindent, this.config);
} }
if (indentFactor > 0) { if (indentFactor > 0) {
writer.write(CharUtil.LF); writer.write(CharUtil.LF);
} }
@@ -551,25 +584,34 @@ public class JSONArray extends JSONGetter<Integer> implements JSON, List<Object>
writer.write(CharUtil.BRACKET_END); writer.write(CharUtil.BRACKET_END);
return writer; return writer;
} }
/** /**
* 初始化 * 初始化
* *
* @param object 数组或集合或JSON数组字符串 * @param source 数组或集合或JSON数组字符串
* @throws JSONException 非数组或集合 * @throws JSONException 非数组或集合
*/ */
private void init(Object object) throws JSONException{ @SuppressWarnings({ "rawtypes", "unchecked" })
if (object instanceof CharSequence) { private void init(Object source) throws JSONException {
if (null == source) {
return;
}
final JSONSerializer serializer = GlobalSerializeMapping.getSerializer(source.getClass());
if (null != serializer && JSONArray.class.equals(TypeUtil.getTypeArgument(serializer.getClass()))) {
// 自定义序列化
serializer.serialize(this, source);
} else if (source instanceof CharSequence) {
// JSON字符串 // JSON字符串
init((CharSequence) object); init((CharSequence) source);
} else { } else {
Iterator<?> iter; Iterator<?> iter;
if (object.getClass().isArray()) {// 数组 if (source.getClass().isArray()) {// 数组
iter = new ArrayIter<>(object); iter = new ArrayIter<>(source);
} else if (object instanceof Iterator<?>) {// Iterator } else if (source instanceof Iterator<?>) {// Iterator
iter = ((Iterator<?>) object); iter = ((Iterator<?>) source);
} else if (object instanceof Iterable<?>) {// Iterable } else if (source instanceof Iterable<?>) {// Iterable
iter = ((Iterable<?>) object).iterator(); iter = ((Iterable<?>) source).iterator();
} else { } else {
throw new JSONException("JSONArray initial value should be a string or collection or array."); throw new JSONException("JSONArray initial value should be a string or collection or array.");
} }
@@ -578,7 +620,7 @@ public class JSONArray extends JSONGetter<Integer> implements JSON, List<Object>
} }
} }
} }
/** /**
* 初始化 * 初始化
* *

View File

@@ -11,6 +11,8 @@ import cn.hutool.core.convert.impl.ArrayConverter;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.TypeUtil; import cn.hutool.core.util.TypeUtil;
import cn.hutool.json.serialize.GlobalSerializeMapping;
import cn.hutool.json.serialize.JSONDeserializer;
/** /**
* JSON转换器 * JSON转换器
@@ -68,6 +70,13 @@ public class JSONConverter implements Converter<JSON> {
return null; return null;
} }
if(value instanceof JSON) {
JSONDeserializer<?> deserializer = GlobalSerializeMapping.getDeserializer(targetType);
if(null != deserializer) {
return (T) deserializer.deserialize((JSON)value);
}
}
Object targetValue = null; Object targetValue = null;
try { try {
targetValue = Convert.convert(targetType, value); targetValue = Convert.convert(targetType, value);

View File

@@ -26,6 +26,9 @@ import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.json.serialize.GlobalSerializeMapping;
import cn.hutool.json.serialize.JSONObjectSerializer;
import cn.hutool.json.serialize.JSONSerializer;
/** /**
* JSON对象<br> * JSON对象<br>
@@ -41,7 +44,7 @@ public class JSONObject extends JSONGetter<String> implements JSON, Map<String,
private static final long serialVersionUID = -330220388580734346L; private static final long serialVersionUID = -330220388580734346L;
/** 默认初始大小 */ /** 默认初始大小 */
private static final int DEFAULT_CAPACITY = 16; public static final int DEFAULT_CAPACITY = 16;
/** JSON的KV持有Map */ /** JSON的KV持有Map */
private final Map<String, Object> rawHashMap; private final Map<String, Object> rawHashMap;
@@ -88,6 +91,16 @@ public class JSONObject extends JSONGetter<String> implements JSON, Map<String,
public JSONObject(int capacity, boolean isIgnoreCase, boolean isOrder) { public JSONObject(int capacity, boolean isIgnoreCase, boolean isOrder) {
this(capacity, JSONConfig.create().setIgnoreCase(isIgnoreCase).setOrder(isOrder)); this(capacity, JSONConfig.create().setIgnoreCase(isIgnoreCase).setOrder(isOrder));
} }
/**
* 构造
*
* @param config JSON配置项
* @since 4.6.5
*/
public JSONObject(JSONConfig config) {
this(DEFAULT_CAPACITY, config);
}
/** /**
* 构造 * 构造
@@ -389,7 +402,7 @@ public class JSONObject extends JSONGetter<String> implements JSON, Map<String,
this.remove(key); this.remove(key);
} else { } else {
InternalJSONUtil.testValidity(value); InternalJSONUtil.testValidity(value);
this.rawHashMap.put(key, JSONUtil.wrap(value, ignoreNullValue)); this.rawHashMap.put(key, JSONUtil.wrap(value, this.config));
} }
return this; return this;
} }
@@ -699,7 +712,7 @@ public class JSONObject extends JSONGetter<String> implements JSON, Map<String,
if (value != bean) { if (value != bean) {
// 防止循环引用 // 防止循环引用
this.rawHashMap.put(prop.getFieldName(), JSONUtil.wrap(value, this.config.isIgnoreNullValue())); this.put(prop.getFieldName(), value);
} }
} }
} }
@@ -715,23 +728,26 @@ public class JSONObject extends JSONGetter<String> implements JSON, Map<String,
* *
* @param source JavaBean或者Map对象或者String * @param source JavaBean或者Map对象或者String
*/ */
@SuppressWarnings({ "rawtypes", "unchecked" })
private void init(Object source) { private void init(Object source) {
if (null == source) { if (null == source) {
return; return;
} }
if (source instanceof Map) { final JSONSerializer serializer = GlobalSerializeMapping.getSerializer(source.getClass());
boolean ignoreNullValue = this.config.isIgnoreNullValue(); if(null != serializer && serializer instanceof JSONObjectSerializer) {
// 自定义序列化
serializer.serialize(this, source);
} else if (source instanceof Map) {
// Map
for (final Entry<?, ?> e : ((Map<?, ?>) source).entrySet()) { for (final Entry<?, ?> e : ((Map<?, ?>) source).entrySet()) {
final Object value = e.getValue(); this.put(Convert.toStr(e.getKey()), e.getValue());
if (false == ignoreNullValue || null != value) {
this.rawHashMap.put(Convert.toStr(e.getKey()), JSONUtil.wrap(value, ignoreNullValue));
}
} }
} else if (source instanceof CharSequence) { } else if (source instanceof CharSequence) {
// 可能为JSON字符串 // 可能为JSON字符串
init((CharSequence) source); init((CharSequence) source);
} else if (source instanceof JSONTokener) { } else if (source instanceof JSONTokener) {
// JSONTokener
init((JSONTokener) source); init((JSONTokener) source);
} else if (source instanceof Number) { } else if (source instanceof Number) {
// ignore Number // ignore Number

View File

@@ -18,9 +18,16 @@ import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.file.FileReader; import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.lang.TypeReference; import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.HexUtil; import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.TypeUtil;
import cn.hutool.json.serialize.GlobalSerializeMapping;
import cn.hutool.json.serialize.JSONArraySerializer;
import cn.hutool.json.serialize.JSONDeserializer;
import cn.hutool.json.serialize.JSONObjectSerializer;
import cn.hutool.json.serialize.JSONSerializer;
/** /**
* JSON工具类 * JSON工具类
@@ -596,12 +603,13 @@ public final class JSONUtil {
* </ul> * </ul>
* *
* @param object 被包装的对象 * @param object 被包装的对象
* @param ignoreNullValue 是否忽略{@code null} 值 * @param jsonConfig JSON选项
* @return 包装后的值null表示此值需被忽略 * @return 包装后的值null表示此值需被忽略
*/ */
public static Object wrap(Object object, boolean ignoreNullValue) { @SuppressWarnings({ "rawtypes", "unchecked" })
public static Object wrap(Object object, JSONConfig jsonConfig) {
if (object == null) { if (object == null) {
return ignoreNullValue ? null : JSONNull.NULL; return jsonConfig.isIgnoreNullValue() ? null : JSONNull.NULL;
} }
if (object instanceof JSON // if (object instanceof JSON //
|| JSONNull.NULL.equals(object) // || JSONNull.NULL.equals(object) //
@@ -612,15 +620,28 @@ public final class JSONUtil {
) { ) {
return object; return object;
} }
// 自定义序列化
final JSONSerializer serializer = GlobalSerializeMapping.getSerializer(object.getClass());
if(null != serializer) {
final Type jsonType = TypeUtil.getTypeArgument(serializer.getClass());
if(null != jsonType) {
if(serializer instanceof JSONObjectSerializer) {
serializer.serialize(new JSONObject(jsonConfig), object);
} else if(serializer instanceof JSONArraySerializer) {
serializer.serialize(new JSONArray(jsonConfig), object);
}
}
}
try { try {
// JSONArray // JSONArray
if (object instanceof Iterable || ArrayUtil.isArray(object)) { if (object instanceof Iterable || ArrayUtil.isArray(object)) {
return new JSONArray(object, ignoreNullValue); return new JSONArray(object, jsonConfig);
} }
// JSONObject // JSONObject
if (object instanceof Map) { if (object instanceof Map) {
return new JSONObject(object, ignoreNullValue); return new JSONObject(object, jsonConfig);
} }
// 日期类型原样保存,便于格式化 // 日期类型原样保存,便于格式化
@@ -636,15 +657,12 @@ public final class JSONUtil {
} }
// Java内部类不做转换 // Java内部类不做转换
final Class<?> objectClass = object.getClass(); if(ClassUtil.isJdkClass(object.getClass())) {
final Package objectPackage = objectClass.getPackage();
final String objectPackageName = objectPackage != null ? objectPackage.getName() : "";
if (objectPackageName.startsWith("java.") || objectPackageName.startsWith("javax.") || objectClass.getClassLoader() == null) {
return object.toString(); return object.toString();
} }
// 默认按照JSONObject对待 // 默认按照JSONObject对待
return new JSONObject(object, ignoreNullValue); return new JSONObject(object, jsonConfig);
} catch (Exception exception) { } catch (Exception exception) {
return null; return null;
} }
@@ -727,6 +745,42 @@ public final class JSONUtil {
public static JSONObject xmlToJson(String xml) { public static JSONObject xmlToJson(String xml) {
return XML.toJSONObject(xml); return XML.toJSONObject(xml);
} }
/**
* 加入自定义的序列化器
*
* @param type 对象类型
* @param serializer 序列化器实现
* @see GlobalSerializeMapping#put(Type, JSONArraySerializer)
* @since 4.6.5
*/
public static void putSerializer(Type type, JSONArraySerializer<?> serializer) {
GlobalSerializeMapping.put(type, serializer);
}
/**
* 加入自定义的序列化器
*
* @param type 对象类型
* @param serializer 序列化器实现
* @see GlobalSerializeMapping#put(Type, JSONObjectSerializer)
* @since 4.6.5
*/
public static void putSerializer(Type type, JSONObjectSerializer<?> serializer) {
GlobalSerializeMapping.put(type, serializer);
}
/**
* 加入自定义的反序列化器
*
* @param type 对象类型
* @param serializer 反序列化器实现
* @see GlobalSerializeMapping#put(Type, JSONDeserializer)
* @since 4.6.5
*/
public static void putDeserializer(Type type, JSONDeserializer<?> deserializer) {
GlobalSerializeMapping.put(type, deserializer);
}
// --------------------------------------------------------------------------------------------- Private method start // --------------------------------------------------------------------------------------------- Private method start
/** /**

View File

@@ -0,0 +1,90 @@
package cn.hutool.json.serialize;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import cn.hutool.json.JSON;
/**
* 全局的序列化和反序列化器映射<br>
* 在JSON和Java对象转换过程中优先使用注册于此处的自定义转换
*
* @author Looly
*
*/
public class GlobalSerializeMapping {
private static Map<Type, JSONSerializer<? extends JSON, ?>> serializerMap;
private static Map<Type, JSONDeserializer<?>> deserializerMap;
/**
* 加入自定义的序列化器
*
* @param type 对象类型
* @param serializer 序列化器实现
*/
public static void put(Type type, JSONArraySerializer<?> serializer) {
putInternal(type, serializer);
}
/**
* 加入自定义的序列化器
*
* @param type 对象类型
* @param serializer 序列化器实现
*/
public static void put(Type type, JSONObjectSerializer<?> serializer) {
putInternal(type, serializer);
}
/**
* 加入自定义的序列化器
*
* @param type 对象类型
* @param serializer 序列化器实现
*/
synchronized private static void putInternal(Type type, JSONSerializer<? extends JSON, ?> serializer) {
if(null == serializerMap) {
serializerMap = new ConcurrentHashMap<>();
}
serializerMap.put(type, serializer);
}
/**
* 加入自定义的反序列化器
*
* @param type 对象类型
* @param serializer 反序列化器实现
*/
synchronized public static void put(Type type, JSONDeserializer<?> deserializer) {
if(null == deserializerMap) {
deserializerMap = new ConcurrentHashMap<>();
}
deserializerMap.put(type, deserializer);
}
/**
* 获取自定义的序列化器,如果未定义返回{@code null}
* @param type 类型
* @return 自定义的序列化器或者{@code null}
*/
public static JSONSerializer<? extends JSON, ?> getSerializer(Type type){
if(null == serializerMap) {
return null;
}
return serializerMap.get(type);
}
/**
* 获取自定义的反序列化器,如果未定义返回{@code null}
* @param type 类型
* @return 自定义的反序列化器或者{@code null}
*/
public static JSONDeserializer<?> getDeserializer(Type type){
if(null == deserializerMap) {
return null;
}
return deserializerMap.get(type);
}
}

View File

@@ -0,0 +1,12 @@
package cn.hutool.json.serialize;
import cn.hutool.json.JSONArray;
/**
* JSON列表的序列化接口用于将特定对象序列化为{@link JSONArray}
*
* @param <V> 对象类型
*
* @author Looly
*/
public interface JSONArraySerializer<V> extends JSONSerializer<JSONArray, V>{}

View File

@@ -0,0 +1,21 @@
package cn.hutool.json.serialize;
import cn.hutool.json.JSON;
/**
* JSON反序列话自定义实现类
*
* @author Looly
*
* @param <T> 反序列化后的类型
*/
public interface JSONDeserializer<T> {
/**
* 反序列化通过实现此方法自定义实现JSON转换为指定类型的逻辑
*
* @param json {@link JSON}
* @return 目标对象
*/
T deserialize(JSON json);
}

View File

@@ -0,0 +1,11 @@
package cn.hutool.json.serialize;
import cn.hutool.json.JSONObject;
/**
* 对象的序列化接口,用于将特定对象序列化为{@link JSONObject}
* @param <V> 对象类型
*
* @author Looly
*/
public interface JSONObjectSerializer<V> extends JSONSerializer<JSONObject, V>{}

View File

@@ -0,0 +1,22 @@
package cn.hutool.json.serialize;
import cn.hutool.json.JSON;
/**
* 序列化接口通过实现此接口实现自定义的对象转换为JSON的操作
*
* @param <T> JSON类型可以是JSONObject或者JSONArray
* @param <V> 对象类型
* @author Looly
*/
public interface JSONSerializer<T extends JSON, V> {
/**
* 序列化实现,通过实现此方法,将指定类型的对象转换为{@link JSON}对象<br>
* 转换后的对象可以为JSONObject也可以为JSONArray首先new一个空的JSON然后将需要的数据字段put到JSON对象中去即可。
*
* @param json JSON可以为JSONObject或者JSONArray
* @param bean 指定类型对象
*/
void serialize(T json, V bean);
}

View File

@@ -0,0 +1,7 @@
/**
* JSON自定义序列化和反序列化接口和默认实现
*
* @author Looly
*
*/
package cn.hutool.json.serialize;

View File

@@ -0,0 +1,55 @@
package cn.hutool.json;
import java.util.Date;
import org.junit.Assert;
import org.junit.Test;
import cn.hutool.json.serialize.JSONDeserializer;
import cn.hutool.json.serialize.JSONObjectSerializer;
import lombok.ToString;
public class CustomSerializeTest {
@Test
public void serializeTest() {
JSONUtil.putSerializer(CustomBean.class, new JSONObjectSerializer<CustomBean>() {
@Override
public void serialize(JSONObject json, CustomBean bean) {
json.put("customName", bean.name);
}
});
CustomBean customBean = new CustomBean();
customBean.name = "testName";
JSONObject obj = JSONUtil.parseObj(customBean);
Assert.assertEquals("testName", obj.getStr("customName"));
}
@Test
public void deserializeTest() {
JSONUtil.putDeserializer(CustomBean.class, new JSONDeserializer<CustomBean>() {
@Override
public CustomBean deserialize(JSON json) {
CustomBean customBean = new CustomBean();
customBean.name = ((JSONObject)json).getStr("customName");
return customBean;
}
});
String jsonStr = "{\"customName\":\"testName\"}";
CustomBean bean = JSONUtil.parseObj(jsonStr).toBean(CustomBean.class);
Assert.assertEquals("testName", bean.name);
}
@ToString
public static class CustomBean {
public String name;
public String b;
public Date date;
}
}

View File

@@ -351,7 +351,7 @@ public class JSONObjectTest {
Assert.assertEquals("yyb\\nbbb", jsonObject.getStrEscaped("name")); Assert.assertEquals("yyb\\nbbb", jsonObject.getStrEscaped("name"));
String bbb = jsonObject.getStr("bbb", "defaultBBB"); String bbb = jsonObject.getStr("bbb", "defaultBBB");
Console.log(bbb); Assert.assertEquals("defaultBBB", bbb);
} }
public static enum TestEnum { public static enum TestEnum {