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()));
Assert.assertEquals(100, set.size());
}
}

View File

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

View File

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

View File

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

View File

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