杰克逊ObjectMapper与任意JSON键

18

我正在使用Jackson 1.9.5在一个Android项目中解析JSON文件。

到目前为止,我还没有遇到任何问题,可以使用以下代码很好地解析文件:

AssetManager mgr = getAssets();
ObjectMapper mapper = new ObjectMapper();

try {
    InputStream ifp = mgr.open("detail_schema.json");
    schema = mapper.readValue(ifp, DetailSchema.class);
} catch (IOException e) {
    e.printStackTrace();
}

在 DetailSchema 类中包含了一些基本类型和类的混合。现在我遇到了一个问题,我想解析一些 JSON 数据,例如以下内容:

"fields": {
    "Suburb": "Paddington",
    "State": "NSW",
    "Post Code": "2074",
    "Lollipop": "Foo Bar Haz"
}

在我无法预先知道映射键的情况下(它们可以是用户定义的),因此,我不确定关联的Java类应该长什么样。

例如,在这个例子中,它可能看起来像:

public class MyClass {

    public String Suburb;
    public String State;
    public String PostCode;
    public String Lollipop;

}

但是对于JSON文件的另一个实例来说,这可能不正确。理想情况下,我需要一种方法让Jackson将值映射到类似于NameValuePair的东西。我怀疑在这种情况下自动对象映射可能不是一个选项-有人可以确认或否认这一点吗?

1个回答

24

您有两个选择。首先,您可以使用ObjectMapper中的readTree, 它会返回一个 JsonNode。使用 JsonNode 很像使用树,因此您可以获取子节点、读取值等等:

InputStream ifp = mgr.open("detail_schema.json");
JsonNode root = mapper.readTree(ifp);
JsonNode fields = root.get("fields");
for (JsonNode children : fields) {
    // ...
}

然后您需要手动构建DetailSchema对象。

或者,您可以让Jackson将其反序列化为Map,在这种情况下,您会使用您的代码,但其中MyClass将如下所示:

public class MyClass {
    public Map<String, Object> fields;

    // getter/setters
}

如果您确定输入是JSON中的文本,则您还可以将地图值类型设置为String。 (实际上,我不确定Jackson执行什么类型强制执行,也许它无论如何都允许任何内容...)

2
你实际上不需要使用自定义类来获取Map,你可以让Jackson直接反序列化到一个Map接口的实现中,例如:Map jsonFields = mapper.readValue(ifp, HashMap.class) - brianmearns
@brianmearns,你应该把它变成一个新的答案! - NeilenMarais

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接