mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-07-21 15:09:48 +08:00
修复JSON反序列化时,引用字段类型的自定义JsonDeserializer无效
This commit is contained in:
43
hutool-json/src/main/java/cn/hutool/json/BeanConverterForJSON.java
Executable file
43
hutool-json/src/main/java/cn/hutool/json/BeanConverterForJSON.java
Executable file
@@ -0,0 +1,43 @@
|
||||
package cn.hutool.json;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.convert.impl.BeanConverter;
|
||||
import cn.hutool.json.serialize.GlobalSerializeMapping;
|
||||
import cn.hutool.json.serialize.JSONDeserializer;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* 针对JSON的Bean转换封装。<br>
|
||||
* 此类时针对5.x中设计缺陷设计的类,在ConverterRegistry中通过反射调用
|
||||
*
|
||||
* @param <T> Bean类型
|
||||
* @since 5.8.6
|
||||
*/
|
||||
public class BeanConverterForJSON<T> extends BeanConverter<T> {
|
||||
|
||||
public BeanConverterForJSON(Type beanType) {
|
||||
super(beanType);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected T convertInternal(final Object value) {
|
||||
final Class<T> targetType = getTargetType();
|
||||
if (value instanceof JSON) {
|
||||
final JSONDeserializer<?> deserializer = GlobalSerializeMapping.getDeserializer(targetType);
|
||||
if (null != deserializer) {
|
||||
//noinspection unchecked
|
||||
return (T) deserializer.deserialize((JSON) value);
|
||||
}
|
||||
|
||||
// issue#2212@Github
|
||||
// 在JSONObject转Bean时,读取JSONObject本身的配置文件
|
||||
if (value instanceof JSONGetter && BeanUtil.hasSetter(targetType)) {
|
||||
final JSONConfig config = ((JSONGetter<?>) value).getConfig();
|
||||
this.copyOptions.setIgnoreError(config.isIgnoreError());
|
||||
}
|
||||
}
|
||||
|
||||
return super.convertInternal(value);
|
||||
}
|
||||
}
|
@@ -28,7 +28,7 @@ public class JSONConverter implements Converter<JSON> {
|
||||
|
||||
static {
|
||||
// 注册到转换中心
|
||||
ConverterRegistry registry = ConverterRegistry.getInstance();
|
||||
final ConverterRegistry registry = ConverterRegistry.getInstance();
|
||||
registry.putCustom(JSON.class, JSONConverter.class);
|
||||
registry.putCustom(JSONObject.class, JSONConverter.class);
|
||||
registry.putCustom(JSONArray.class, JSONConverter.class);
|
||||
|
@@ -768,11 +768,16 @@ public class JSONUtil {
|
||||
if (null != serializer) {
|
||||
final Type jsonType = TypeUtil.getTypeArgument(serializer.getClass());
|
||||
if (null != jsonType) {
|
||||
final JSON json;
|
||||
if (serializer instanceof JSONObjectSerializer) {
|
||||
serializer.serialize(new JSONObject(jsonConfig), object);
|
||||
json = new JSONObject(jsonConfig);
|
||||
} else if (serializer instanceof JSONArraySerializer) {
|
||||
serializer.serialize(new JSONArray(jsonConfig), object);
|
||||
json = new JSONArray(jsonConfig);
|
||||
} else{
|
||||
throw new JSONException("Unsupported JSONSerializer type: " + serializer.getClass());
|
||||
}
|
||||
serializer.serialize(json, object);
|
||||
return json;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -810,7 +815,7 @@ public class JSONUtil {
|
||||
|
||||
// 默认按照JSONObject对待
|
||||
return new JSONObject(object, jsonConfig);
|
||||
} catch (Exception exception) {
|
||||
} catch (final Exception exception) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
54
hutool-json/src/test/java/Issue2555Test.java
Executable file
54
hutool-json/src/test/java/Issue2555Test.java
Executable file
@@ -0,0 +1,54 @@
|
||||
import cn.hutool.json.JSON;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.hutool.json.serialize.JSONDeserializer;
|
||||
import cn.hutool.json.serialize.JSONObjectSerializer;
|
||||
import lombok.Data;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class Issue2555Test {
|
||||
|
||||
@Test
|
||||
public void serAndDeserTest(){
|
||||
JSONUtil.putSerializer(MyType.class, new MySerializer());
|
||||
JSONUtil.putDeserializer(MyType.class, new MyDeserializer());
|
||||
|
||||
final SimpleObj simpleObj = new SimpleObj();
|
||||
final MyType child = new MyType();
|
||||
child.setAddress("addrValue1");
|
||||
simpleObj.setMyType(child);
|
||||
|
||||
final String json = JSONUtil.toJsonStr(simpleObj);
|
||||
Assert.assertEquals("{\"myType\":{\"addr\":\"addrValue1\"}}", json);
|
||||
|
||||
//MyDeserializer不会被调用
|
||||
final SimpleObj simpleObj2 = JSONUtil.toBean(json, SimpleObj.class);
|
||||
Assert.assertEquals("addrValue1", simpleObj2.getMyType().getAddress());
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class MyType {
|
||||
private String address;
|
||||
}
|
||||
@Data
|
||||
public static class SimpleObj {
|
||||
private MyType myType;
|
||||
}
|
||||
|
||||
public static class MySerializer implements JSONObjectSerializer<MyType> {
|
||||
@Override
|
||||
public void serialize(JSONObject json, MyType bean) {
|
||||
json.set("addr", bean.getAddress());
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyDeserializer implements JSONDeserializer<MyType>{
|
||||
@Override
|
||||
public MyType deserialize(JSON json) {
|
||||
final MyType myType = new MyType();
|
||||
myType.setAddress(((JSONObject)json).getStr("addr"));
|
||||
return myType;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user