java - 使用 Jackson 从 ObjectNode 获取嵌套的 JSON 元素

标签 java json jackson

我有一个 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/

相关文章:

java - 防止多个异步调用同时进行而不阻塞

java - 小数点后的固定位数

java - sprite 碰到边界时如何循环(android 游戏开发)

java - jackson & JSONAnySetter : NullPointer Exception during Serialization/Deserialization

java - jackson 序列化奇怪的输出

Java - 让 ArrayList 值在游戏中旋转

c# - 在 JSON 中找不到必需的属性 'probability'。小路

javascript - 如何在 PHP 中将 JavaScript 文字对象转换为 Json 对象

javascript - 如何将变量传递到 Magento 中的 Data.php 中?

java - Jackson EnumMap key 序列化