Java 当json包含type属性时,jackson能否确定要反序列化的根对象类型?
假设json的序列化包括实际对象的类名,在类上使用以下注释:Java 当json包含type属性时,jackson能否确定要反序列化的根对象类型?,java,json,jackson,Java,Json,Jackson,假设json的序列化包括实际对象的类名,在类上使用以下注释: @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@type") class MyClass { String foo; } 例如,json是: {"@type": "com.example.MyClass", "foo": "bar"} 是否可以在不指定类型的情况下对其进行反序列化?我的意思
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@type")
class MyClass {
String foo;
}
例如,json是:
{"@type": "com.example.MyClass", "foo": "bar"}
是否可以在不指定类型的情况下对其进行反序列化?我的意思是甚至不是超级类型。就像:
objectMapper.readValue(value, Object.class);
这实际上不起作用,它带来了一张地图。好吧,这当然是可能的,尽管我个人从未用过杰克逊那样的方式。您可以将其反序列化为
JsonNode
对象,然后将其转换为正确的类型
final ObjectMapper objectMapper = new ObjectMapper();
final MyClass myClass = new MyClass();
myClass.foo = "bar";
// Serialize
final String json = objectMapper.writeValueAsString(myClass);
// Deserialize
final JsonNode jsonNode = objectMapper.readTree(json);
// Get the @type
final String type = jsonNode.get("@type").asText();
// Create a Class-object
final Class<?> cls = Class.forName(type);
// And convert it
final Object o = objectMapper.convertValue(jsonNode, cls);
System.out.println(o.getClass());
final ObjectMapper ObjectMapper=new ObjectMapper();
最终MyClass MyClass=新MyClass();
myClass.foo=“bar”;
//连载
最后一个字符串json=objectMapper.writeValueAsString(myClass);
//反序列化
final JsonNode JsonNode=objectMapper.readTree(json);
//获取@type
最终字符串类型=jsonNode.get(“@type”).asText();
//创建一个类对象
最终类cls=Class.forName(类型);
//并转换它
最终对象o=objectMapper.convertValue(jsonNode,cls);
System.out.println(o.getClass());
输出为:
我的班级
是的,但有一个警告:您提供的类型必须包含您指定的
@JsonTypeInfo
<代码>对象。类将没有,除非您使用“混合注释”将其关联
但是,如果需要为(声明类型的)java.lang.Object
的属性添加类型信息,则可能需要启用默认类型:有关详细信息,请参阅ObjectMapper.enableDefaultTyping(…)
。
这实际上将允许包含(和使用)更大类别的类的类型信息,而无需添加注释
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
MyClass original = new MyClass();
original.foo = "hello";
String json = mapper.writeValueAsString(original);
MyClass foo = (MyClass) mapper.readValue(json, MyClass.class);
这应该是可行的,而且非常方便。您想要使用的是。哦,是的,我想这是可行的。我想知道是否有一种更内置的方式,但我想这没有任何意义,因为Jackson可能不知道我是如何配置JsonTypeInfo的,而不知道这个类。非常感谢。如果您知道JSON在反序列化时表示
MyClass
,那么它会起作用。我的问题是指一个场景,您不知道对象的类型。这就是我目前正在尝试处理的情况。如果你不知道类型,你可以只分配给一个对象。getClass()将告诉您它是什么类型。