This commit is contained in:
Looly 2022-06-20 18:52:19 +08:00
parent 1a0d7b51a7
commit 270bec0f37
5 changed files with 55 additions and 42 deletions

View File

@ -19,4 +19,6 @@ public class UUIDTest {
ThreadUtil.concurrencyTest(100, ()-> set.add(UUID.fastUUID().toString())); ThreadUtil.concurrencyTest(100, ()-> set.add(UUID.fastUUID().toString()));
Assert.assertEquals(100, set.size()); Assert.assertEquals(100, set.size());
} }
} }

View File

@ -46,12 +46,12 @@ public class JSONConverter implements Converter {
/** /**
* JSON递归转换<br> * JSON递归转换<br>
* 首先尝试JDK类型转换如果失败尝试JSON转Bean<br> * 首先尝试JDK类型转换如果失败尝试JSON转Bean<br>
* 如果遇到{@link JSONBeanParser}则调用其{@link JSONBeanParser#parse(Object)}方法转换 * 如果遇到{@link JSONDeserializer}则调用其{@link JSONDeserializer#deserialize(JSON)}方法转换
* *
* @param <T> 转换后的对象类型 * @param <T> 转换后的对象类型
* @param targetType 目标类型 * @param targetType 目标类型
* @param value * @param value
* @param config JSON配置项 * @param config JSON配置项
* @return 目标类型的值 * @return 目标类型的值
* @throws ConvertException 转换失败 * @throws ConvertException 转换失败
*/ */
@ -62,26 +62,24 @@ public class JSONConverter implements Converter {
} }
// since 5.7.8增加自定义Bean反序列化接口和特殊对象的自定义转换 // since 5.7.8增加自定义Bean反序列化接口和特殊对象的自定义转换
if(targetType instanceof Class){ if (targetType instanceof Class) {
final Class<?> targetClass = (Class<?>) targetType; final Class<?> targetClass = (Class<?>) targetType;
if(targetClass.isInstance(value)){ if (targetClass.isInstance(value)) {
return (T) value; return (T) value;
} } else if (JSONDeserializer.class.isAssignableFrom(targetClass)) {
// 自定义反序列化
if (JSONBeanParser.class.isAssignableFrom(targetClass)){ if (value instanceof JSON) {
// 自定义对象转换 final JSONDeserializer<T> target = (JSONDeserializer<T>) ConstructorUtil.newInstanceIfPossible(targetClass);
@SuppressWarnings("rawtypes") if (null == target) {
final JSONBeanParser target = (JSONBeanParser) ConstructorUtil.newInstanceIfPossible(targetClass); throw new ConvertException("Can not instance target: [{}]", targetType);
if(null == target){ }
throw new ConvertException("Can not instance [{}]", targetType); return target.deserialize((JSON) value);
} }
target.parse(value); } else if (targetClass == byte[].class && value instanceof CharSequence) {
return (T) target;
} else if(targetClass == byte[].class && value instanceof CharSequence){
// bytes二进制反序列化默认按照Base64对待 // bytes二进制反序列化默认按照Base64对待
// issue#I59LW4 // issue#I59LW4
return (T) Base64.decode((CharSequence) value); return (T) Base64.decode((CharSequence) value);
}else if(targetClass.isAssignableFrom(Date.class) || targetClass.isAssignableFrom(TemporalAccessor.class)){ } else if (targetClass.isAssignableFrom(Date.class) || targetClass.isAssignableFrom(TemporalAccessor.class)) {
// 用户指定了日期格式获取日期属性时使用对应格式 // 用户指定了日期格式获取日期属性时使用对应格式
final String valueStr = Convert.toStr(value); final String valueStr = Convert.toStr(value);
if (null == valueStr) { if (null == valueStr) {
@ -90,10 +88,10 @@ public class JSONConverter implements Converter {
// 日期转换支持自定义日期格式 // 日期转换支持自定义日期格式
final String format = getDateFormat(config); final String format = getDateFormat(config);
if(null != format){ if (null != format) {
if(targetClass.isAssignableFrom(Date.class)){ if (targetClass.isAssignableFrom(Date.class)) {
return (T) new DateConverter(format).convert(targetClass, valueStr); return (T) new DateConverter(format).convert(targetClass, valueStr);
}else{ } else {
return (T) new TemporalAccessorConverter(format).convert(targetClass, valueStr); return (T) new TemporalAccessorConverter(format).convert(targetClass, valueStr);
} }
} }
@ -107,9 +105,9 @@ public class JSONConverter implements Converter {
* JSON递归转换为Bean<br> * JSON递归转换为Bean<br>
* 首先尝试JDK类型转换如果失败尝试JSON转Bean * 首先尝试JDK类型转换如果失败尝试JSON转Bean
* *
* @param <T> 转换后的对象类型 * @param <T> 转换后的对象类型
* @param targetType 目标类型 * @param targetType 目标类型
* @param value JSON格式 * @param value JSON格式
* @param ignoreError 是否忽略转换错误 * @param ignoreError 是否忽略转换错误
* @return 目标类型的值 * @return 目标类型的值
* @throws ConvertException 转换失败 * @throws ConvertException 转换失败
@ -121,16 +119,18 @@ public class JSONConverter implements Converter {
return null; return null;
} }
if(value instanceof JSON){ if (value instanceof JSON) {
final JSON valueJson = (JSON) value;
// 全局自定义反序列化
final JSONDeserializer<?> deserializer = GlobalSerializeMapping.getDeserializer(targetType); final JSONDeserializer<?> deserializer = GlobalSerializeMapping.getDeserializer(targetType);
if(null != deserializer) { if (null != deserializer) {
return (T) deserializer.deserialize((JSON) value); return (T) deserializer.deserialize(valueJson);
} }
// issue#2212@Github // issue#2212@Github
// 在JSONObject转Bean时读取JSONObject本身的配置文件 // 在JSONObject转Bean时读取JSONObject本身的配置文件
if(targetType instanceof Class && BeanUtil.hasSetter((Class<?>) targetType)){ if (targetType instanceof Class && BeanUtil.hasSetter((Class<?>) targetType)) {
final JSONConfig config = ((JSON) value).getConfig(); final JSONConfig config = valueJson.getConfig();
final Converter converter = new BeanConverter(InternalJSONUtil.toCopyOptions(config).setIgnoreError(ignoreError)); final Converter converter = new BeanConverter(InternalJSONUtil.toCopyOptions(config).setIgnoreError(ignoreError));
return ignoreError ? converter.convert(targetType, value, null) return ignoreError ? converter.convert(targetType, value, null)
: (T) converter.convert(targetType, value); : (T) converter.convert(targetType, value);
@ -154,11 +154,12 @@ public class JSONConverter implements Converter {
/** /**
* 获取配置文件中的日期格式无格式返回{@code null} * 获取配置文件中的日期格式无格式返回{@code null}
*
* @param config JSON配置 * @param config JSON配置
* @return 日期格式无返回{@code null} * @return 日期格式无返回{@code null}
*/ */
private static String getDateFormat(final JSONConfig config){ private static String getDateFormat(final JSONConfig config) {
if(null != config){ if (null != config) {
final String format = config.getDateFormat(); final String format = config.getDateFormat();
if (StrUtil.isNotBlank(format)) { if (StrUtil.isNotBlank(format)) {
return format; return format;

View File

@ -1,6 +1,7 @@
package cn.hutool.json; package cn.hutool.json;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.serialize.JSONDeserializer;
/** /**
* JSON支持<br> * JSON支持<br>
@ -8,15 +9,15 @@ import cn.hutool.core.bean.BeanUtil;
* *
* @author Looly * @author Looly
*/ */
public class JSONSupport implements JSONString, JSONBeanParser<JSON> { public class JSONSupport implements JSONString, JSONDeserializer<Object> {
/** /**
* JSON String转Bean * JSON String转Bean
* *
* @param jsonString JSON String * @param jsonString JSON String
*/ */
public void parse(final String jsonString) { public void deserialize(final String jsonString) {
parse(new JSONObject(jsonString)); deserialize(new JSONObject(jsonString));
} }
/** /**
@ -25,9 +26,10 @@ public class JSONSupport implements JSONString, JSONBeanParser<JSON> {
* @param json JSON * @param json JSON
*/ */
@Override @Override
public void parse(final JSON json) { public Object deserialize(final JSON json) {
final JSONSupport support = JSONConverter.jsonToBean(getClass(), json, false); final JSONSupport support = JSONConverter.jsonToBean(getClass(), json, false);
BeanUtil.copyProperties(support, this); BeanUtil.copyProperties(support, this);
return this;
} }
/** /**

View File

@ -2,9 +2,14 @@ package cn.hutool.json.serialize;
import cn.hutool.json.JSON; import cn.hutool.json.JSON;
import java.lang.reflect.Type;
/** /**
* JSON自定义反序列化接口<br> * JSON自定义反序列化接口实现JSON to Bean使用方式为
* 此接口主要针对一些特殊对象的反序列化自定义转换规则配合GlobalSerializeMapping可以全局设定某一类对象的自定义转换而无需修改发Bean的结构 * <ul>
* <li>定义好反序列化规则使用{@link GlobalSerializeMapping#put(Type, JSONDeserializer)}关联指定类型与转换器实现反序列化</li>
* <li>使Bean实现此接口调用{@link #deserialize(JSON)}解析字段返回this即可</li>
* </ul>
* *
* @param <T> 反序列化后的类型 * @param <T> 反序列化后的类型
* @author Looly * @author Looly

View File

@ -1,10 +1,11 @@
package cn.hutool.json; package cn.hutool.json;
import cn.hutool.json.serialize.JSONDeserializer;
import lombok.Data; import lombok.Data;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
public class JSONBeanParserTest { public class JSONDeserializerTest {
@Test @Test
public void parseTest(){ public void parseTest(){
@ -16,15 +17,17 @@ public class JSONBeanParserTest {
} }
@Data @Data
static class TestBean implements JSONBeanParser<JSONObject>{ static class TestBean implements JSONDeserializer<Object> {
private String name; private String name;
private String address; private String address;
@Override @Override
public void parse(final JSONObject value) { public Object deserialize(final JSON value) {
this.name = value.getStr("customName"); final JSONObject valueObj = (JSONObject) value;
this.address = value.getStr("customAddress"); this.name = valueObj.getStr("customName");
this.address = valueObj.getStr("customAddress");
return this;
} }
} }
} }