当json包含type属性时,jackson能否确定要反序列化的根对象类型?

假设序列化为json包含实际对象的类名,在Class上使用此批注:

@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); 

它实际上不起作用,它带回了一张地图。

嗯,这当然可以做到这一点,虽然我个人从未使用过jackson。 您可以将其反序列化为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()); 

输出是:

我的课

  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 Polymorphic Deserialization 。

是的,但有一个警告:你必须提供的类型包括你指定的@JsonTypeInfo 。 除非使用“混合注释”来关联它,否则Object.class将不会有。

但是,如果需要为(声明的类型) java.lang.Object属性添加类型信息,则可能需要启用默认类型:有关详细信息,请参阅ObjectMapper.enableDefaultTyping(...) 。 这实际上可以为更大类的类包含(和使用)类型信息,而无需添加注释。