2

我知道如何在 Jackson 中解包Object但我找不到任何关于如何解包两层的示例。

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

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

我尝试了以下方法,但它没有使resultsvalue 成为顶级对象。

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

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

4

2 回答 2

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>>() {});
于 2017-09-19T19:31:45.033 回答
0
@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>对你来说没问题,那么你可以像这样使用。

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);
于 2017-09-19T19:04:51.017 回答