[英]Get nested JSON elements from ObjectNode using Jackson
I have an ObjectNode, that looks as follows我有一个 ObjectNode,如下所示
{
"Header":{
"sub-header1":{
"#field":"value",
"#field":"value",
},
"sub-header2":{
"field":"",
"field":"",
"field":"",
"panel_field":{
"value":"",
"value":""
}
}
}
Now, what I want to do is to get all the fields from sub-headers in a list.现在,我想要做的是从列表中的子标题中获取所有字段。 This is the method that I'm employing
这是我正在使用的方法
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;
}
But, I'm only getting headers in the list like {sub-header1, sub-header2}
, instead of fields.但是,我只在列表中获取标题,例如
{sub-header1, sub-header2}
,而不是字段。 How can I fix this?我怎样才能解决这个问题? I'd really appreciate any kind of help.
我真的很感激任何形式的帮助。
EDIT: While @sfiss
's answer helped a great deal, I still wanted to find a way to do so without hardcoding the loop-logic and this answer turned out to be the exact thing I was looking for.编辑:虽然
@sfiss
的回答有很大帮助,但我仍然想找到一种方法来做到这一点,而无需对循环逻辑进行硬编码,结果这个答案正是我正在寻找的。
Well, it's simple, you are not iterating deep enough (field list is on third level).嗯,这很简单,你迭代的不够深(字段列表在第三层)。 If you know the structure of your JSON, just iterate until you find the desired fields:
如果您知道 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;
}
}
However, I would argue that it is simpler to let jackson serialize the JSON into a convenient data structure, and you just use the POJO's getters to obtain your values.但是,我认为让 jackson 将 JSON 序列化为方便的数据结构更简单,您只需使用 POJO 的 getter 来获取您的值。 That would also make it more clear than handling the
JsonNode
.这也比处理
JsonNode
更清楚。
Just FYI, I edited your JSON slightly and used Java 8 SAM conversions to create iterables for the foreach-loops from the iterators, but you can still use your code and iterate one more level using while
and iterators.仅供参考,我稍微编辑了您的 JSON,并使用 Java 8 SAM 转换为迭代器的 foreach 循环创建可迭代对象,但您仍然可以使用您的代码并使用
while
和迭代器再迭代一个级别。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.