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

时间:2012-10-17 10:04:26

标签: java jackson

我正在尝试反序列化一个相当复杂的POJO JSON,我需要在其中定义一个特定的属性名称来解析,但是找不到这个相当简单的功能。

假设一个类:

class Example {
  int id;
  Map<String,Object> extras;
}

并且Jackson正在将POJO正确地序列化为JSON,其中地图被序列化为键值映射,就像预期一样:

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

现在我想告诉Jackson明确地按照实际类型反序列化extras对象。所以我需要告诉杰克逊以某种方式将“object1”映射到A型,将“object2”映射到B型。

这可能吗?谢谢。

4 个答案:

答案 0 :(得分:7)

有很好的指南如何处理它:http://www.cowtowncoder.com/blog/archives/2010/03/entry_372.html

另一个教程:
http://programmerbruce.blogspot.de/2011/05/deserialize-json-with-jackson-into.html

可以修改第二个教程中的第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);
}

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

如果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;
}

答案 3 :(得分:0)

使用自定义反序列化器可以实现这一点;例如,请参阅此link。在一个坚果壳中,你需要告诉杰克逊应该解组一个字段的类型;但是,如果您的序列化数据(JSON)正在动态变化,这可能会出错。

然后您可以轻松地注释您的字段的设置器,如下所示:

ObjectA value;

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