Jackson JsonNode

时间:2020-01-09 10:36:12  来源:igfitidea点击:

Hymanson JsonNode类(com.fasterxml.Hymanson.databind.JsonNode)是Hymanson的JSON树形模型(对象图模型)。Hyman逊可以将JSON读入" JsonNode"实例,然后将" JsonNode"写出至JSON。这份HymansonJsonNode教程将说明如何将JSON反序列化为JsonNode以及将JsonNode序列化为JSON。该HymansonJsonNode教程还将说明如何从头开始构建JsonNode对象图,因此我们以后可以将它们序列化为JSON。

JsonNode与ObjectNode

Hymanson的JsonNode类是不可变的。这意味着,我们实际上不能直接构建" JsonNode"实例的对象图。相反,我们将创建JsonNode子类ObjectNode的对象图。作为JsonNode的子类,我们可以在可以使用JsonNode的任何地方使用ObjectNode。在本教程的后面,我们将看到如何构建" ObjectNode"图。

从JSON读取JsonNode

要与Hymanson一起将JSON读入JsonNode中,首先要创建一个Hymanson ObjectMapper实例。在" ObjectMapper"实例上,我们调用" readTree()",并将JSON源作为参数传递。这是将JSON反序列化为JsonNode的示例:

String json = "{ \"f1\" : \"v1\" } ";

ObjectMapper objectMapper = new ObjectMapper();

JsonNode jsonNode = objectMapper.readTree(json);

System.out.println(jsonNode.get("f1").asText());

将JsonNode写入JSON

要将Hymanson的JSON写入一个JsonNode,还需要一个Hymanson ObjectMapper实例。在" ObjectMapper"上,我们可以调用" writeValueAsString()"方法,或者任何适合我们需要的写入方法。这是将JSON写入JsonNode的示例:

ObjectMapper objectMapper = new ObjectMapper();

JsonNode jsonNode = readJsonIntoJsonNode();

String json = objectMapper.writeValueAsString(jsonNode);

" readJsonIntoJsonNode()"方法只是我创建的一种方法,它将JSON字符串解析为" JsonNode",因此我们要编写" JsonNode"。 readJsonIntoJsonNode()的确切内容对于此示例而言并不重要,只要我们知道它会产生一个JsonNode对象即可。重要的是以下一行调用了ObjectWriter的writeValueAsString()方法,该方法将JsonNode写入一个JSON字符串中。

writeValueAsString()相比,Hymanson ObjectMapper具有更多的写方法。我们可以在Hymanson的ObjectMapper教程中看到这些方法。

获取JsonNode字段

" JsonNode"可以像JSON对象一样具有字段。假设我们已将以下JSON解析为JsonNode

{
    "field1" : "value1",
    "field2" : 999
}

这个JSON对象具有两个名为field1field2的字段。如果我们有一个表示上述JSON对象的HymansonJsonNode,则可以这样获得两个字段:

JsonNode jsonNode = ... //parse above JSON into a JsonNode

JsonNode field1 = jsonNode.get("field1");
JsonNode field2 = jsonNode.get("field2");

注意,即使两个字段都是String字段,get()方法也总是返回一个" JsonNode"来表示该字段。

在路径获取JsonNode字段

Hymanson的JsonNode有一种特殊的方法,称为at()。 at()方法可以从JSON图中以给定的JsonNode为根的任何地方访问JSON字段。想象一下,JSON结构如下所示:

{
  "identification" :  {
        "name" : "James",
        "ssn: "ABC123552"
    }
}

如果将此JSON解析为JsonNode,则可以使用at()方法访问name字段,如下所示:

JsonNode nameNode = jsonNode.at("/identification/name");

注意传递给at()方法的参数:字符串/ identification / name。这是一个JSON路径表达式。此路径表达式指定从根" JsonNode"到我们想要访问其值的字段的完整路径。这类似于从文件系统根目录到Unix文件系统中文件的路径。

请注意,JSON路径表达式必须以斜杠字符(/字符)开头。

at()方法返回一个JsonNode,它表示我们请求的JSON字段。要获取该字段的实际值,我们需要调用下一部分介绍的方法之一。如果没有节点与给定的路径表达式匹配,则将返回" null"。

转换JsonNode字段

Hymanson的JsonNode类包含一组可以将字段值转换为另一种数据类型的方法。例如,将String字段值转换为long,反之亦然。这是将" JsonNode"字段转换为一些更常见的数据类型的示例:

String f2Str = jsonNode.get("f2").asText();
double f2Dbl = jsonNode.get("f2").asDouble();
int    f2Int = jsonNode.get("f2").asInt();
long   f2Lng = jsonNode.get("f2").asLong();

假设" f2"字段包含值" 123456",然后可以将该值转换为字符串," double"," int"和" long",如上所示。

使用默认值转换

如果一个字段在JsonNode内可以为null,那么当我们尝试转换它时可以提供一个默认值。这是使用默认值调用转换方法的示例:

ObjectMapper objectMapper = new ObjectMapper();

String json = "{ \"f1\":\"Hello\", \"f2\":null }";

JsonNode jsonNode = objectMapper.readTree(json);

String f2Value = jsonNode.get("f2").asText("Default");

如我们在示例中的JSON字符串中所见,声明了f2字段,但将其设置为null。在这种情况下,调用jsonNode.get(" f2")。asText(" Default")将返回默认值,在此示例中为字符串Default

asDouble(),asInt()和asLong()方法也可以采用默认参数值,以防我们尝试从中获取值的字段为null时返回这些默认值。

请注意,如果JSON中的字段未明确设置为null,但JSON中没有该字段,则调用jsonNode.get(" fieldName")将返回Javanull值,我们不能调用asInt()asDouble()asLong()或者asText()。如果我们尝试这样做,将会得到NullPointerException。这是说明此情况的示例:

ObjectMapper objectMapper = new ObjectMapper();

String json = "{ \"f1\":\"Hello\" }";

JsonNode jsonNode = objectMapper.readTree(json);

JsonNode f2FieldNode = jsonNode.get("f2");

运行此代码后,f2FieldNode变量将指向null

处理空字段值

让我花点时间探讨一下我们如何在HymansonJsonNode中处理null值。有两种方法可以使JsonNode内部的字段为空。第一种方法是,如果从创建JsonNode的JSON中完全丢失了该字段。这是一个仅包含单个字段的简单JSON字符串的示例:

ObjectMapper objectMapper = new ObjectMapper();

String json = "{ \"f1\":\"Hello\" }";

JsonNode jsonNode = objectMapper.readTree(json);

JsonNode f2FieldNode = jsonNode.get("f2");

在上面的示例中,没有名为f2的字段。因此,jsonNode.get(" f2")方法调用将返回null。请看以下示例:

ObjectMapper objectMapper = new ObjectMapper();

String json = "{ \"f1\":\"Hello\" \"f2\":null }";

JsonNode jsonNode = objectMapper.readTree(json);

JsonNode f2FieldNode = jsonNode.get("f2");

在此示例中,JSON字符串包含一个名为" f2"的字段,但其值为" null"。这次jsonNode.get(" f2")方法调用将返回一个有效的JsonNode,代表值null。我们可以通过调用isNull()方法来检查JsonNode是否代表null值,如下所示:

boolean isFieldValueNull = f2FieldNode.isNull();

为了对JsonNode字段进行正确的" null"检查,我们必须执行以下操作:

JsonNode fieldNode = parentNode.get("fieldName");

if(fieldNode == null || fieldNode.isNull()) {
    // the field is either not present in parentNode, or explicitly set to null .
}

当在" parentNode"中缺少该字段时,以及当该字段存在但设置为" null"时,此" if"语句将捕获该字段。

遍历JsonNode图

可以像其他任何对象图一样遍历表示JSON对象或者JSON数组的JsonNode。我们可以通过迭代其嵌套字段(或者数组的嵌套元素)来实现。这是遍历表示JSON对象或者JSON数组的JsonNode的所有嵌套字段的示例:

public static void traverse(JsonNode root){
    
    if(root.isObject()){
        Iterator<String> fieldNames = root.fieldNames();

        while(fieldNames.hasNext()) {
            String fieldName = fieldNames.next();
            JsonNode fieldValue = root.get(fieldName);
            traverse(fieldValue);
        }
    } else if(root.isArray()){
        ArrayNode arrayNode = (ArrayNode) root;
        for(int i = 0; i < arrayNode.size(); i++) {
            JsonNode arrayElement = arrayNode.get(i);
            traverse(arrayElement);
        }
    } else {
        // JsonNode root represents a single value field - do something with it.
        
    }
}

注意,我们可能必须修改此示例以适合我们自己的用例。确切的实现将在某种程度上取决于我们对遍历的节点需要执行的操作。但是,我们可以将上面的示例用作模板,然后对其进行修改,直到它满足要求为止。

创建一个ObjectNode

如前所述,JsonNode类是不可变的。要创建JsonNode对象图,我们必须能够对图中的JsonNode实例进行突变,例如设置属性值和子级" JsonNode"实例等。由于是不可变的,因此无法直接通过" JsonNode"来实现。

相反,我们将创建一个ObjectNode实例,该实例是JsonNode的子类。这是一个通过HymansonObjectMappercreateObjectNode()方法创建ObjectNode的示例:

ObjectMapper objectMapper = new ObjectMapper();

ObjectNode objectNode = objectMapper.createObjectNode();

设置ObjectNode字段

要在Hymanson的ObjectNode上设置字段,可以调用其set()方法,并传递字段名称String和JsonNode作为参数。这是在HymansonObjectNode上设置字段的示例:

ObjectMapper objectMapper = new ObjectMapper();
ObjectNode parentNode = objectMapper.createObjectNode();

JsonNode childNode = readJsonIntoJsonNode();

parentNode.set("child1", childNode);

再次,想象一下readJsonIntoJsonNode()会生成一些我们想设置为ObjectNode父对象上的子对象的JsonNode对象。

将ObjectNode字段放入原始值

ObjectNode类还具有一组方法,使我们能够放置(设置)字段的原始值。这比尝试将原始值转换为JsonNode并使用set()设置要容易。这是一个使用put()方法为ObjectNode上的字段设置字符串值的示例:

objectNode.put("field1", "value1");
objectNode.put("field2", 123);
objectNode.put("field3", 999.999);

移除字段

ObjectNode类具有一个称为remove()的方法,该方法可用于从ObjectNode中删除字段。这是一个示例,该示例通过其Hymanson的ObjectNode的remove()方法删除该字段:

objectNode.remove("fieldName");

迭代JsonNode字段

我们可以使用JsonNodefields()方法从JsonNode获取所有字段。这是一个使用fields()从JsonNode获取和迭代所有字段的示例:

Iterator<Map.Entry<String, JsonNode>> fields = jsonNode.fields();
    
while(fields.hasNext()) {
    Map.Entry<String, JsonNode> field = fields.next();
    String   fieldName  = field.getKey();
    JsonNode fieldValue = field.getValue();

    System.out.println(fieldName + " = " + fieldValue.asText());
}

迭代JsonNode字段名称

JsonNode类具有一个名为fieldNames()的方法,该方法返回一个迭代器,使我们可以迭代JsonNode的所有字段名称。我们可以使用字段名称来获取字段值。这是一个迭代Hymanson的所有字段名称和值的示例:

Iterator<String> fieldNames = jsonNode.fieldNames();

while(fieldNames.hasNext()) {
    String fieldName = fieldNames.next();

    JsonNode field = jsonNode.get(fieldName);
}