Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can jackson determine root object type to deserialize to when json includes type property?

Tags:

java

json

jackson

Assume serialization to json includes the class name of the actual object, using this annotation on the Class:

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@type")
class MyClass {
    String foo;
}

So json is for example:

{"@type": "com.example.MyClass", "foo": "bar"}

Can this be deserialized without specifying the type? And I mean not even the super type. Just something like:

objectMapper.readValue(value, Object.class);

which doesn't actually work, it brings back a Map.

like image 422
Nazaret K. Avatar asked Feb 07 '15 16:02

Nazaret K.


1 Answers

Well, it is certainly possible to do that although I have personally never used Jackson that way. You can deserialize it to a JsonNode object and then convert it to the proper type.

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

The output is:

MyClass

like image 119
wassgren Avatar answered Sep 21 '22 16:09

wassgren