关于json:如何在Java中修改JsonNode?

How to modify JsonNode in Java?

我需要在Java中更改JSON属性的值,我可以正确获取该值,但无法修改JSON。

这是下面的代码

1
2
3
4
5
6
7
8
9
10
  JsonNode blablas = mapper.readTree(parser).get("blablas");
    for (JsonNode jsonNode : blablas) {
        String elementId = jsonNode.get("element").asText();
        String value = jsonNode.get("value").asText();
        if (StringUtils.equalsIgnoreCase(elementId,"blabla")) {
            if(value != null && value.equals("YES")){
                 // I need to change the node to NO then save it into the JSON
            }
        }
    }

做这个的最好方式是什么?


JsonNode是不可变的,旨在用于解析操作。但是,可以将其转换为允许突变的ObjectNode(和ArrayNode):

1
((ObjectNode)jsonNode).put("value","NO");

对于数组,可以使用:

1
((ObjectNode)jsonNode).putArray("arrayName").add(object.ge??tValue());


添加一个答案,就像其他人在接受的答案的注释中赞成的那样,在尝试转换为ObjectNode(包括我自己)时,他们会收到此异常:

1
2
Exception in thread"main" java.lang.ClassCastException:
com.fasterxml.jackson.databind.node.TextNode cannot be cast to com.fasterxml.jackson.databind.node.ObjectNode

解决方案是获取"父"节点并执行put,有效地替换整个节点,而不管原始节点的类型如何。

如果需要使用节点的现有值来"修改"该节点,请执行以下操作:

  • get JsonNode的值/数组
  • 在该值/数组上执行修改
  • 继续在父级上调用put
  • 代码,目标是修改subfield,它是NodeANode1的子节点:

    1
    2
    3
    4
    5
    JsonNode nodeParent = someNode.get("NodeA")
                    .get("Node1");

    // Manually modify value of 'subfield', can only be done using the parent.
    ((ObjectNode) nodeParent).put('subfield',"my-new-value-here");

    学分:

    感谢wassgreen @,我从这里得到了灵感


    @ Sharon-Ben-Asher的答案是可以的。

    但就我而言,对于数组我必须使用:

    1
    ((ArrayNode) jsonNode).add("value");

    我认为您可以将其转换为ObjectNode并使用put方法。像这样

    ObjectNode o = (ObjectNode) jsonNode;
    o.put("value","NO");


    您需要获取ObjectNode类型的对象才能设置值。
    看看这个


    只是为了理解其他可能无法清楚了解整个画面的人,下面的代码对我来说是找到一个字段,然后对其进行更新

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    ObjectMapper mapper = new ObjectMapper();
    JsonNode rootNode = mapper.readTree(JsonString);    
    JsonPointer valueNodePointer = JsonPointer.compile("/GrandObj/Obj/field");
    JsonPointer containerPointer = valueNodePointer.head();
    JsonNode parentJsonNode = rootNode.at(containerPointer);

    if (!parentJsonNode.isMissingNode() && parentJsonNode.isObject()) {
        ObjectNode parentObjectNode = (ObjectNode) parentJsonNode;
        //following will give you just the field name.
        //e.g. if pointer is /grandObject/Object/field
        //JsonPoint.last() will give you /field
        //remember to take out the / character
        String fieldName = valueNodePointer.last().toString();
        fieldName = fieldName.replace(Character.toString(JsonPointer.SEPARATOR), StringUtils.EMPTY);
        JsonNode fieldValueNode = parentObjectNode.get(fieldName);

        if(fieldValueNode != null) {
            parentObjectNode.put(fieldName,"NewValue");
        }
    }