简体   繁体   中英

Trivial JSON jackson polymorphic deserialization

Struggling with something which looks like trivial and should work without any problems. I have JSON with "@class" property and without knowing it's class on the moment of invocation readValue() want to deserialize it into the object of the class referenced by "@class". What I get back instead is "LinkedHashMap".

@Test
public void toJsonAndBack() throws Exception {
    ObjectMapper mapper = new ObjectMapper();
    String json = mapper.writeValueAsString(new Sample("id"));
    assertTrue(json.contains("@class"));
    Sample obj = (Sample)mapper.readValue(json, Object.class);
}

@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS)
static class Sample {
    private String id;

    public Sample() {
    }

    public Sample(String id) {
        this.id = id;
    }

    public String getId() {
        return id;
    }
}

Sorry, if dup, but couldn't find exactly the same problem. The most of people have more complicated cases where there is base class, which is also annotated, etc. These cases actually work fine.

I'm using jackson 2.6.6

Jackson converts it into LinkedhashMap , so that later, we can you use its convert method to convert given LinkedhashMap into custom Object. So here you need to add one more step into it.

Eg:

ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(new Sample("id"));
Object obj = mapper.readValue(json, Object.class);
Sample sample = mapper.convertValue(obj, Sample.class);

So you can preserve this obj somewhere, and can convert it into Sample class at your convenience.

Apparently adding this line makes this test work:

mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);

In that case annotation on the Sample class is not necessary.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM