如何使用抽象类将JSON数据数组反序列化为POJO?

时间:2016-10-24 21:33:16

标签: java json jackson deserialization pojo

我正在尝试将一些JSON映射到pojo中。我已经看到如何使用实际数据中的信息来做到这一点,但我的情况是,我真的没有任何确定数据如何不同的东西,但我确实知道列表是由什么构成的。在下面的例子中,我可能会得到一个囚犯或建筑物的清单,但在这种情况下,我知道我得到了一个囚犯名单。

下面给出了JSON(我知道嵌套的数据是奇怪的,但我得到的是JSON,我无法控制它。)

{
    "data": [{
        "data": {
            "create_date": "2015-09-30",
            "building": "12",
            "dob": "2/11/1965",
            "gender": "M",
            "location": {
                "zip": "10459"
            },
            "name": {
                "first": "James",
                "last": "Bond"

            },
            "id": "45"
        },
        "uri": "/prisoner/45"
    }, {
        "data": {
            "create_date": "2015-09-27",
            "building": "12",
            "dob": "12/15/1985",
            "gender": "M",
            "location": {
                "zip": "10459"
            },
            "name": {
                "first": "Hans",
                "last": "Gruber"

            },
            "id": "56"
        },
        "uri": "/prisoner/56"
    }],
    "totals": {
        "total": 2,
        "page": 1
    },
    "links": [{
        "uri": "/prisoners?limit=2"
    }]
}

我有一个 Data 对象,其中包含一个总计对象和一个链接对象。我还有一个 Datum 对象的Collection(在本例中是一个列表),其中包含嵌套的 Data 对象数组。 Datum 对象具有 Thing 抽象类以及 Uri 字符串。我有囚徒建筑类,扩展了 Thing 。在上面的JSON中,我知道我正在获得一份囚犯名单。

我目前的代码:

ObjectMapper mapper = new ObjectMapper();
Data data = mapper.readValue(responseJSON.toString(), Data.class);

如果我进入 Datum 并将 Thing 对象更改为囚犯对象,它就能完美运行。我的问题是如何让它接受囚犯构建,但仍然有抽象的 Thing 类,或至少使它成为现实可以更通用。我知道我可以创建几个 Datum 类,但我相信必须有一种方法可以拥有1个Datum类。实际上,我可以获得数十种不同的数据可能性,而不仅仅是我的例子中的2。

1 个答案:

答案 0 :(得分:4)

你的意思是,你知道在阅读这个价值时你会有什么类型的东西?因为在这种情况下,您可以参数化数据(即Data<T extends Thing>),并将类型参数传播到Datum以指定您拥有的Thing的子类。然后,当你调用readValue时,你需要告诉杰克逊有关参数化的类型,这可以像这样静态地完成:

mapper.readValue(jsonString, new TypeReference<Data<Prisoner>>(){});

可以通过使用ObjectMapper中提供的TypeFactory构造参数化类型来动态完成。类似的东西:

mapper.readValue("", mapper.getTypeFactory()
                           .constructParametricType(Data.class, thingSubclass));