简体   繁体   English

Jackson自定义属性 - 多态属性的类型映射名称

[英]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. 我试图反序列化一个相当复杂的POJO JSON,我需要在其中定义一个特定的属性名称来进行类型解析,但是找不到这个相当简单的功能。

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: 和Jackson正确地将POJO序列化为JSON,其中地图被序列化为键值映射,就像预期的那样:

{...
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. 所以我需要告诉Jackson以某种方式将“object1”映射到Type A,将“object2”映射到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 有一个很好的指南如何处理它: 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 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: 可以修改第二个教程中的第6个示例,并且反序列化器将具有类似于以下内容的循环:

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. 最简单的方法是启用所谓的“默认类型” - 它大致相当于添加@JsonTypeInfo注释(它支持多态类型处理) - 这会在值中添加类型信息。 So: 所以:

ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping();

If the Extras map contains only those 2 objects (object1 and object2) you can do the following 如果Extras映射仅包含那两个对象(object1和object2),则可以执行以下操作

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. 但是,如果序列化数据(JSON)动态变化,这可能会出错。

You can then easily annotate your field's setter like so: 然后,您可以轻松地注释您的字段的setter,如下所示:

ObjectA value;

@JsonDeserialize(using=ObjectADeserializer.class)
public void setValue(ObjectA objectAValue) {
   this.value = objectAValue;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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