假设序列化到json包含实际对象的类名,在类上使用此注释:
@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);
实际上不起作用,它会带回一张地图。
答案 0 :(得分:7)
嗯,我当然可以这样做,尽管我个人从未使用过杰克逊。您可以将其反序列化为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());
输出结果为:
MyClass的
答案 1 :(得分:2)
是的,但有一个警告:您必须提供的类型包括您指定的@JsonTypeInfo
。除非您使用“混合注释”来关联它,否则Object.class
将不会有。
但是,如果您需要为(声明的类型)java.lang.Object
的属性添加类型信息,您可能希望启用默认类型:有关详细信息,请参阅ObjectMapper.enableDefaultTyping(...)
。
这实际上可以为更大类别的类别信息包含(和使用),而无需添加注释。
答案 2 :(得分:2)
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);
这应该有效并且非常方便。
答案 3 :(得分:2)