4

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

假设一个类:

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

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

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

现在我想告诉杰克逊通过它们的实际类型显式反序列化额外对象。所以我需要告诉杰克逊以某种方式将“object1”映射到类型 A,将“object2”映射到类型 B。

这可能吗?谢谢。

4

4 回答 4

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);
}
于 2012-10-17T10:11:36.990 回答
1

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

ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping();
于 2012-10-17T23:28:48.893 回答
0

如果 Extras 地图仅包含这 2 个对象(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;
}
于 2012-10-17T10:28:24.853 回答
0

这可以使用自定义解串器来实现;有关示例,请参见此链接。简而言之,您需要告诉 Jackson 应该将字段解组为哪种类型;但是,如果您的序列化数据 (JSON) 是动态变化的,那么这可能很容易出错。

然后,您可以像这样轻松地注释字段的设置器:

ObjectA value;

@JsonDeserialize(using=ObjectADeserializer.class)
public void setValue(ObjectA objectAValue) {
   this.value = objectAValue;
}
于 2012-10-17T10:29:56.053 回答