【问题标题】:Jackson ObjectMapper with arbitrary JSON keys具有任意 JSON 键的 Jackson ObjectMapper
【发布时间】:2012-07-14 22:59:13
【问题描述】:

我在一个 Android 项目中使用 Jackson 1.9.5 来解析 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 之类的东西。我怀疑在这种情况下自动对象映射可能不是一个选项 - 有人可以确认或否认这一点吗?

【问题讨论】:

    标签: java android json jackson android-assets


    【解决方案1】:

    你有两个选择。您可以使用readTree in ObjectMapper,它返回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 的强制执行类型是什么,也许它无论如何都会允许任何事情......)

    【讨论】:

    • 您实际上不必使用自定义类来获取Map,您可以让Jackson 直接反序列化为Map 接口的实现,例如:Map jsonFields = mapper.readValue(ifp, HashMap.class)
    • @brianmearns 你应该把它变成一个新的答案!
    猜你喜欢
    • 1970-01-01
    • 2011-10-13
    • 2020-10-18
    • 1970-01-01
    • 2019-10-31
    • 2014-05-06
    • 1970-01-01
    • 1970-01-01
    • 2017-09-23
    相关资源
    最近更新 更多