mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-07-21 15:09:48 +08:00
add custom serialize support
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
* 【core】 ArrayUtil增加distinct方法
|
||||
* 【http】 去除log模块依赖,Cookie中去除日志提示,body方法传入JSON对象废弃,未来移除json模块依赖
|
||||
* 【extra】 添加MyNLP支持(issue#519@Github)
|
||||
* 【json】 添加自定义序列化反序列化支持(issue#I1052A@Gitee)
|
||||
|
||||
### Bug修复
|
||||
|
||||
|
@@ -59,12 +59,13 @@ public class ClassUtil {
|
||||
|
||||
/**
|
||||
* 是否为顶层类,既定义在包中的类,而非定义在类中的内部类
|
||||
*
|
||||
* @param clazz 类
|
||||
* @return 是否为顶层类
|
||||
* @since 4.5.7
|
||||
*/
|
||||
public static boolean isTopLevelClass(Class<?> clazz) {
|
||||
if(null == clazz) {
|
||||
if (null == clazz) {
|
||||
return false;
|
||||
}
|
||||
return null == getEnclosingClass(clazz);
|
||||
@@ -1018,4 +1019,28 @@ public class ClassUtil {
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
@@ -16,6 +16,9 @@ import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.CharUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
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>
|
||||
@@ -32,7 +35,7 @@ public class JSONArray extends JSONGetter<Integer> implements JSON, List<Object>
|
||||
private static final long serialVersionUID = 2664900568717612292L;
|
||||
|
||||
/** 默认初始大小 */
|
||||
private static final int DEFAULT_CAPACITY = 10;
|
||||
public static final int DEFAULT_CAPACITY = 10;
|
||||
|
||||
/** 持有原始数据的List */
|
||||
private final List<Object> rawList;
|
||||
@@ -59,6 +62,17 @@ public class JSONArray extends JSONGetter<Integer> implements JSON, List<Object>
|
||||
this(initialCapacity, JSONConfig.create());
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造<br>
|
||||
* 默认使用{@link ArrayList} 实现
|
||||
*
|
||||
* @param config JSON配置项
|
||||
* @since 4.6.5
|
||||
*/
|
||||
public JSONArray(JSONConfig config) {
|
||||
this(DEFAULT_CAPACITY, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造<br>
|
||||
* 默认使用{@link ArrayList} 实现
|
||||
@@ -152,7 +166,26 @@ public class JSONArray extends JSONGetter<Integer> implements JSON, List<Object>
|
||||
* @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);
|
||||
}
|
||||
// -------------------------------------------------------------------------------------------------------------------- Constructor start
|
||||
@@ -330,7 +363,7 @@ public class JSONArray extends JSONGetter<Integer> implements JSON, List<Object>
|
||||
|
||||
@Override
|
||||
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
|
||||
@@ -366,7 +399,7 @@ public class JSONArray extends JSONGetter<Integer> implements JSON, List<Object>
|
||||
}
|
||||
final ArrayList<Object> list = new ArrayList<>(c.size());
|
||||
for (Object object : c) {
|
||||
list.add(JSONUtil.wrap(object, this.config.isIgnoreNullValue()));
|
||||
list.add(JSONUtil.wrap(object, this.config));
|
||||
}
|
||||
return rawList.addAll(index, list);
|
||||
}
|
||||
@@ -389,17 +422,17 @@ public class JSONArray extends JSONGetter<Integer> implements JSON, List<Object>
|
||||
|
||||
@Override
|
||||
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
|
||||
public void add(int index, Object element) {
|
||||
if (index < 0) {
|
||||
throw new JSONException("JSONArray[" + index + "] not found.");
|
||||
throw new JSONException("JSONArray[{}] not found.", index);
|
||||
}
|
||||
if (index < this.size()) {
|
||||
InternalJSONUtil.testValidity(element);
|
||||
this.rawList.add(index, JSONUtil.wrap(element, this.config.isIgnoreNullValue()));
|
||||
this.rawList.add(index, JSONUtil.wrap(element, this.config));
|
||||
} else {
|
||||
while (index != this.size()) {
|
||||
this.add(JSONNull.NULL);
|
||||
@@ -528,12 +561,12 @@ public class JSONArray extends JSONGetter<Integer> implements JSON, List<Object>
|
||||
final boolean isIgnoreNullValue = this.config.isIgnoreNullValue();
|
||||
boolean isFirst = true;
|
||||
for (Object obj : this.rawList) {
|
||||
if(ObjectUtil.isNull(obj) && isIgnoreNullValue) {
|
||||
if (ObjectUtil.isNull(obj) && isIgnoreNullValue) {
|
||||
continue;
|
||||
}
|
||||
if (isFirst) {
|
||||
isFirst = false;
|
||||
}else {
|
||||
} else {
|
||||
writer.write(CharUtil.COMMA);
|
||||
}
|
||||
|
||||
@@ -555,21 +588,30 @@ public class JSONArray extends JSONGetter<Integer> implements JSON, List<Object>
|
||||
/**
|
||||
* 初始化
|
||||
*
|
||||
* @param object 数组或集合或JSON数组字符串
|
||||
* @param source 数组或集合或JSON数组字符串
|
||||
* @throws JSONException 非数组或集合
|
||||
*/
|
||||
private void init(Object object) throws JSONException{
|
||||
if (object instanceof CharSequence) {
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
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字符串
|
||||
init((CharSequence) object);
|
||||
init((CharSequence) source);
|
||||
} else {
|
||||
Iterator<?> iter;
|
||||
if (object.getClass().isArray()) {// 数组
|
||||
iter = new ArrayIter<>(object);
|
||||
} else if (object instanceof Iterator<?>) {// Iterator
|
||||
iter = ((Iterator<?>) object);
|
||||
} else if (object instanceof Iterable<?>) {// Iterable
|
||||
iter = ((Iterable<?>) object).iterator();
|
||||
if (source.getClass().isArray()) {// 数组
|
||||
iter = new ArrayIter<>(source);
|
||||
} else if (source instanceof Iterator<?>) {// Iterator
|
||||
iter = ((Iterator<?>) source);
|
||||
} else if (source instanceof Iterable<?>) {// Iterable
|
||||
iter = ((Iterable<?>) source).iterator();
|
||||
} else {
|
||||
throw new JSONException("JSONArray initial value should be a string or collection or array.");
|
||||
}
|
||||
|
@@ -11,6 +11,8 @@ import cn.hutool.core.convert.impl.ArrayConverter;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.TypeUtil;
|
||||
import cn.hutool.json.serialize.GlobalSerializeMapping;
|
||||
import cn.hutool.json.serialize.JSONDeserializer;
|
||||
|
||||
/**
|
||||
* JSON转换器
|
||||
@@ -68,6 +70,13 @@ public class JSONConverter implements Converter<JSON> {
|
||||
return null;
|
||||
}
|
||||
|
||||
if(value instanceof JSON) {
|
||||
JSONDeserializer<?> deserializer = GlobalSerializeMapping.getDeserializer(targetType);
|
||||
if(null != deserializer) {
|
||||
return (T) deserializer.deserialize((JSON)value);
|
||||
}
|
||||
}
|
||||
|
||||
Object targetValue = null;
|
||||
try {
|
||||
targetValue = Convert.convert(targetType, value);
|
||||
|
@@ -26,6 +26,9 @@ import cn.hutool.core.util.CharUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
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>
|
||||
@@ -41,7 +44,7 @@ public class JSONObject extends JSONGetter<String> implements JSON, Map<String,
|
||||
private static final long serialVersionUID = -330220388580734346L;
|
||||
|
||||
/** 默认初始大小 */
|
||||
private static final int DEFAULT_CAPACITY = 16;
|
||||
public static final int DEFAULT_CAPACITY = 16;
|
||||
|
||||
/** JSON的KV持有Map */
|
||||
private final Map<String, Object> rawHashMap;
|
||||
@@ -89,6 +92,16 @@ public class JSONObject extends JSONGetter<String> implements JSON, Map<String,
|
||||
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);
|
||||
} else {
|
||||
InternalJSONUtil.testValidity(value);
|
||||
this.rawHashMap.put(key, JSONUtil.wrap(value, ignoreNullValue));
|
||||
this.rawHashMap.put(key, JSONUtil.wrap(value, this.config));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@@ -699,7 +712,7 @@ public class JSONObject extends JSONGetter<String> implements JSON, Map<String,
|
||||
|
||||
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
|
||||
*/
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private void init(Object source) {
|
||||
if (null == source) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (source instanceof Map) {
|
||||
boolean ignoreNullValue = this.config.isIgnoreNullValue();
|
||||
final JSONSerializer serializer = GlobalSerializeMapping.getSerializer(source.getClass());
|
||||
if(null != serializer && serializer instanceof JSONObjectSerializer) {
|
||||
// 自定义序列化
|
||||
serializer.serialize(this, source);
|
||||
} else if (source instanceof Map) {
|
||||
// Map
|
||||
for (final Entry<?, ?> e : ((Map<?, ?>) source).entrySet()) {
|
||||
final Object value = e.getValue();
|
||||
if (false == ignoreNullValue || null != value) {
|
||||
this.rawHashMap.put(Convert.toStr(e.getKey()), JSONUtil.wrap(value, ignoreNullValue));
|
||||
}
|
||||
this.put(Convert.toStr(e.getKey()), e.getValue());
|
||||
}
|
||||
} else if (source instanceof CharSequence) {
|
||||
// 可能为JSON字符串
|
||||
init((CharSequence) source);
|
||||
} else if (source instanceof JSONTokener) {
|
||||
// JSONTokener
|
||||
init((JSONTokener) source);
|
||||
} else if (source instanceof Number) {
|
||||
// ignore Number
|
||||
|
@@ -18,9 +18,16 @@ import cn.hutool.core.io.IORuntimeException;
|
||||
import cn.hutool.core.io.file.FileReader;
|
||||
import cn.hutool.core.lang.TypeReference;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.ClassUtil;
|
||||
import cn.hutool.core.util.HexUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
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工具类
|
||||
@@ -596,12 +603,13 @@ public final class JSONUtil {
|
||||
* </ul>
|
||||
*
|
||||
* @param object 被包装的对象
|
||||
* @param ignoreNullValue 是否忽略{@code null} 值
|
||||
* @param jsonConfig JSON选项
|
||||
* @return 包装后的值,null表示此值需被忽略
|
||||
*/
|
||||
public static Object wrap(Object object, boolean ignoreNullValue) {
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public static Object wrap(Object object, JSONConfig jsonConfig) {
|
||||
if (object == null) {
|
||||
return ignoreNullValue ? null : JSONNull.NULL;
|
||||
return jsonConfig.isIgnoreNullValue() ? null : JSONNull.NULL;
|
||||
}
|
||||
if (object instanceof JSON //
|
||||
|| JSONNull.NULL.equals(object) //
|
||||
@@ -613,14 +621,27 @@ public final class JSONUtil {
|
||||
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 {
|
||||
// JSONArray
|
||||
if (object instanceof Iterable || ArrayUtil.isArray(object)) {
|
||||
return new JSONArray(object, ignoreNullValue);
|
||||
return new JSONArray(object, jsonConfig);
|
||||
}
|
||||
// JSONObject
|
||||
if (object instanceof Map) {
|
||||
return new JSONObject(object, ignoreNullValue);
|
||||
return new JSONObject(object, jsonConfig);
|
||||
}
|
||||
|
||||
// 日期类型原样保存,便于格式化
|
||||
@@ -636,15 +657,12 @@ public final class JSONUtil {
|
||||
}
|
||||
|
||||
// Java内部类不做转换
|
||||
final Class<?> objectClass = object.getClass();
|
||||
final Package objectPackage = objectClass.getPackage();
|
||||
final String objectPackageName = objectPackage != null ? objectPackage.getName() : "";
|
||||
if (objectPackageName.startsWith("java.") || objectPackageName.startsWith("javax.") || objectClass.getClassLoader() == null) {
|
||||
if(ClassUtil.isJdkClass(object.getClass())) {
|
||||
return object.toString();
|
||||
}
|
||||
|
||||
// 默认按照JSONObject对待
|
||||
return new JSONObject(object, ignoreNullValue);
|
||||
return new JSONObject(object, jsonConfig);
|
||||
} catch (Exception exception) {
|
||||
return null;
|
||||
}
|
||||
@@ -728,6 +746,42 @@ public final class JSONUtil {
|
||||
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
|
||||
/**
|
||||
* 转义不可见字符<br>
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -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>{}
|
@@ -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);
|
||||
}
|
@@ -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>{}
|
@@ -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);
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* JSON自定义序列化和反序列化接口和默认实现
|
||||
*
|
||||
* @author Looly
|
||||
*
|
||||
*/
|
||||
package cn.hutool.json.serialize;
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -351,7 +351,7 @@ public class JSONObjectTest {
|
||||
Assert.assertEquals("yyb\\nbbb", jsonObject.getStrEscaped("name"));
|
||||
|
||||
String bbb = jsonObject.getStr("bbb", "defaultBBB");
|
||||
Console.log(bbb);
|
||||
Assert.assertEquals("defaultBBB", bbb);
|
||||
}
|
||||
|
||||
public static enum TestEnum {
|
||||
|
Reference in New Issue
Block a user