如何告诉杰克逊将子元素作为顶级元素

时间:2017-09-19 18:41:35

标签: java jackson jackson-databind

我知道杰克逊如何解开 Object,但我找不到任何关于如何解开两层的例子。

Sharepoint API EndPoints按以下格式返回所有内容:

{
    "d": {
        "results": [
            {
               /* lots objects with lots of properties 
                  that are irrelevant to the question */
            }
        ]
    }
}

我尝试了以下操作,并没有使results成为顶级对象。

this.om.readerFor(new TypeReference<List<User>>() {})
       .withRootName("d")
       .readValue(response.parseAsString());

如何告诉Jackson开始将results解析为顶级Array ,而无需创建自定义对象层次结构无需编写自定义反序列化程序。我有一个自定义对象,注释会填充,我想要TypeSafety所以Map<String,Object>不是我想要的。

2 个答案:

答案 0 :(得分:2)

可能不是最有效的方法,但可以先尝试将对象解析为树,然后导航到所需的节点。像这样:

mapper.readerFor(new TypeReference<List<User>>() {}).readValue(mapper.readTree(json).get("d").get("results"))‌​;

易于阅读:

mapper.convertValue(mapper.readTree(json).get("d").get("‌​results"), new TypeReference<List<User>>() {});

答案 1 :(得分:-1)

@JsonRootName("d")
class Data {
    public Map<String, Object>[] results;
}

ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);

Map<String, Object> results = new LinkedHashMap<>();
results.put("key1", "val1");
results.put("key2", "val2");

Data expected = new Data();
expected.results = new Map[1];
expected.results[0] = results;

String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(expected);
Data actual = mapper.readerFor(Data.class).readValue(json);

Json字符串看起来像:

{
  "d" : {
    "results" : [ {
      "key1" : "val1",
      "key2" : "val2"
    } ]
  }
}

PS 如果您不关心concreate对象并且Map<String, Object>对您来说没问题,那么您可以这样使用。< / em>的

Map<String, Object> results = (Map<String, Object>)((List<?>)mapper.readerFor(Map.class).<Map<String, Map<String, ?>>>readValues(json).next().get("d").get("results")).get(0);