我有一个 ObjectNode,如下所示
{
"Header":{
"sub-header1":{
"#field":"value",
"#field":"value",
},
"sub-header2":{
"field":"",
"field":"",
"field":"",
"panel_field":{
"value":"",
"value":""
}
}
}
现在,我想要做的是从列表中的子标题中获取所有字段。这是我正在使用的方法
public static List<String> getDocumentFields(ObjectNode jsonDocumentNode) {
List<String> documentFields = new ArrayList<>();
Iterator<JsonNode> fields = jsonDocumentNode.elements();
while (fields.hasNext()) {
JsonNode jsonNode = fields.next();
Iterator<Map.Entry<String, JsonNode>> jsonFields = jsonNode.fields();
while (jsonFields.hasNext()) {
Map.Entry<String, JsonNode> jsonNodeEntry = jsonFields.next();
documentFields.add(jsonNodeEntry.getKey());
}
}
return documentFields;
}
但是,我只在列表中获取标题,例如 {sub-header1, sub-header2}
,而不是字段。我怎样才能解决这个问题?我真的很感激任何形式的帮助。
编辑: 虽然 @sfiss 的回答有很大帮助,但我仍然想找到一种方法来做到这一点,而无需对循环逻辑进行硬编码和 this事实证明答案正是我正在寻找的东西。
最佳答案
嗯,很简单,您迭代的深度不够(字段列表位于第三级)。如果您知道 JSON 的结构,只需迭代直到找到所需的字段:
public class MyTest {
@Test
public void testJson() throws IOException {
final String json = getJson();
final JsonNode jsonDocumentNode = new ObjectMapper().readTree(json);
final List<String> fields = getDocumentFields((ObjectNode) jsonDocumentNode);
assertThat(fields, Matchers.contains("#field1", "#field2", "field1", "field2", "field3", "panel_field"));
}
public static String getJson() {
return "{\r\n" +
" \"Header\":{\r\n" +
" \"sub-header1\":{\r\n" +
" \"#field1\":\"value\",\r\n" +
" \"#field2\":\"value\"\r\n" +
" },\r\n" +
" \"sub-header2\":{\r\n" +
" \"field1\":\"\",\r\n" +
" \"field2\":\"\",\r\n" +
" \"field3\":\"\",\r\n" +
" \"panel_field\":{\r\n" +
" \"value1\":\"\",\r\n" +
" \"value2\":\"\"\r\n" +
" }\r\n" +
" } \r\n" +
" }\r\n" +
"}";
}
public static List<String> getDocumentFields(final ObjectNode jsonDocumentNode) {
final List<String> documentFields = new ArrayList<>();
for (final JsonNode header : (Iterable<JsonNode>) jsonDocumentNode::elements) {
for (final JsonNode subheader : (Iterable<JsonNode>) header::elements) {
for (final Map.Entry<String, JsonNode> field : (Iterable<Map.Entry<String, JsonNode>>) subheader::fields) {
documentFields.add(field.getKey());
}
}
}
return documentFields;
}
}
但是,我认为让 jackson 将 JSON 序列化为方便的数据结构会更简单,并且您只需使用 POJO 的 getter 来获取您的值即可。这也比处理 JsonNode
更清晰。
仅供引用,我稍微编辑了您的 JSON,并使用 Java 8 SAM 转换为迭代器中的 foreach 循环创建可迭代对象,但您仍然可以使用您的代码并使用 while
再迭代一层和迭代器。
关于java - 使用 Jackson 从 ObjectNode 获取嵌套的 JSON 元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60053279/