Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何告诉Jackson使子元素成为顶级元素_Java_Jackson_Jackson Databind - Fatal编程技术网

Java 如何告诉Jackson使子元素成为顶级元素

Java 如何告诉Jackson使子元素成为顶级元素,java,jackson,jackson-databind,Java,Jackson,Jackson Databind,我知道如何在Jackson中展开对象,但我找不到任何关于如何展开两层的示例 Sharepoint API终结点以以下格式返回所有内容: { "d": { "results": [ { /* lots objects with lots of properties that are irrelevant to the question */ }

我知道如何在Jackson中展开
对象
,但我找不到任何关于如何展开两层的示例

Sharepoint API终结点以以下格式返回所有内容:

{
    "d": {
        "results": [
            {
               /* lots objects with lots of properties 
                  that are irrelevant to the question */
            }
        ]
    }
}
我尝试了以下操作,但它不会使
结果
值成为顶级对象

this.om.readerFor(new TypeReference<List<User>>() {})
       .withRootName("d")
       .readValue(response.parseAsString());
this.om.reader(新类型引用(){})
.withRootName(“d”)
.readValue(response.parseAsString());
我如何告诉
Jackson
开始将
结果
解析为顶级
数组
,而无需创建自定义对象层次结构而无需编写自定义反序列化程序。我有一个自定义对象,它被注释,这将填充,我想要
TypeSafety
,所以
Map
不是我想要的

@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);
p.S.如果您不关心concreate对象,并且
Map
适合您,那么您可以这样使用

Map results=(Map)((List)mapper.readerFor(Map.class).readValues(json.next().get(“d”).get(“results”).get(0);

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

mapper.readerFor(new TypeReference<List<User>>() {}).readValue(mapper.readTree(json).get("d").get("results"))‌​;
mapper.readerFor(newtypereference(){}).readValue(mapper.readTree(json).get(“d”).get(“results”))‌​;
易于阅读:

mapper.convertValue(mapper.readTree(json).get("d").get("‌​results"), new TypeReference<List<User>>() {});
mapper.convertValue(mapper.readTree(json).get(“d”).get(“‌​结果”),新类型引用(){});

“无需创建对象层次结构”-我不想像我在问题中所说的那样为此需要一个特殊的类。如果您不关心具体的对象,并且Map对您来说是可以的,那么我想您可以这样做:Map results=(Map)((List)mapper.readerFor(Map.class).readValues(json).next().get(“d”).get(“results”).get(0);我独立地提出了这个解决方案的变体,我认为这是获得我想要的东西的最佳方式。至于高效,它无论如何都必须对它进行一次解析,因此传入
JsonNode
以开始转换在任何有意义的方面都不会降低效率。这只是做它通常做的事情,但分为两个明确的阶段。如果它必须在
空间
时间
方面非常高效,我就不会使用
Json
更不用说
SharePoint
:-)@JarrodRoberson是的,我也认为性能在这里不是什么大问题。其实我发布的是我从来没有测试过性能,总是依赖别人的话。在基本测试之后:从
time
的角度来看,它看起来并没有那么糟糕,对于用户中只有一个字段的简单情况,速度可能慢2倍,而对于复杂的json,速度可能慢30%。从空间角度看,它的效率比wrapper对象或自定义反序列化程序或内联
JsonParser
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>>() {});