当前位置: 动力学知识库 > 问答 > 编程问答 >

java - Jackson Custom Property-Name to Type Mapping for Polymorphic Properties

问题描述:

I am trying to deserialize a rather complex POJOs JSON, where I would need to define a specific property-name to type resolution, but yet faild fininding this rather simple feature.

assume a class like:

class Example {

int id;

Map<String,Object> extras;

}

and Jackson is serializing the POJO correctly to JSON where the map is serialized to a key-value map just like expected:

{...

id:5,

extras:{object1:{...}, object2:{...}}

...}

now I would like to tell Jackson to explicitly deserialize the extras objects by their actual type. So I need to tell Jackson somehow to map "object1" to Type A and "object2" to type B.

Is this possible? Thanks.

网友答案:

There is nice guide how to deal with it: http://www.cowtowncoder.com/blog/archives/2010/03/entry_372.html

And another tutorial:
http://programmerbruce.blogspot.de/2011/05/deserialize-json-with-jackson-into.html

The 6th example from the second tutorial could be modified and deserializer would have loop with something similar to:

Map<String, Class> types = ...// map of supported types
JsonToken token = jsonParser.nextToken();
if(token == JsonToken.FIELD_NAME){ // "object1" etc.
    String name = jsonParser.getCurrentName();
    Class type = types.get(name);
    Object object = jsonParser.readValueAs(type);
}
网友答案:

The easiest way is to enable so-called "default typing" -- it does roughly equivalent of adding @JsonTypeInfo annotation (which enables support polymorphic type handling) -- and this adds type information in values. So:

ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping();
网友答案:

If the Extras map contains only those 2 objects (object1 and object2) you can do the following

class TypeA {
    // TypeA body
}

class TypeB {
    // TypeB body
}

class Extras {
    private TypeA object1;
    private TypeB object2;
    // Getters and setters
}

class Example {
    int id;
    Extras extras;
}
网友答案:

This is possible using a custom deserializer; see this link, for examples. In a nut shell, you need to tell Jackson what type a field should be unmarshalled to; although, this might be error prone if your serialized data (JSON) is dynamically changing.

You can then easily annotate your field's setter like so:

ObjectA value;

@JsonDeserialize(using=ObjectADeserializer.class)
public void setValue(ObjectA objectAValue) {
   this.value = objectAValue;
}
分享给朋友:
您可能感兴趣的文章:
随机阅读: