如何在Java中修改JsonNode?


109

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

这是下面的代码

  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
            }
        }
    }

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


1
您可以将JsonNode转换为Java Map,例如resultMap = mapper.convertValue(aJsonNode, Map.class);,在Map中对其进行修改,然后将该Map更改回JsonNode。只是说。
MikeJRamsey56年

Answers:


195

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

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

对于数组,可以使用:

((ObjectNode)jsonNode).putArray("arrayName").add(object.ge‌​tValue());

4
尝试使用需要更改值的数字类型。我遇到了以下例外情况:Exception in thread "main" java.lang.ClassCastException: com.fasterxml.jackson.databind.node.IntNode cannot be cast to com.fasterxml.jackson.databind.node.ObjectNode
balboa_21

您需要尝试“ IntNode”
mulya

6

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

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

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

如果需要使用节点的现有值来“修改”该节点:

  1. get 的值/数组 JsonNode
  2. 在该值/数组上执行修改
  3. 继续呼叫put父项。

目的是修改的代码subfield,它是NodeAand 的子节点Node1

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 @,我从这里得到了灵感


5

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

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

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

4

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

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



0

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

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");
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.