Wie ändere ich JsonNode in Java?


109

Ich muss den Wert eines JSON-Attributs in Java ändern. Ich kann den Wert korrekt abrufen, aber ich konnte den JSON nicht ändern.

Hier ist der Code unten

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

Was ist der beste Weg, dies zu tun?


1
Sie können den JsonNode in eine Java-Map konvertieren, z. B. resultMap = mapper.convertValue(aJsonNode, Map.class);in der Map ändern und diese Map dann wieder in einen JsonNode ändern. Nur sagen.
MikeJRamsey56

Antworten:


195

JsonNodeist unveränderlich und für den Analysevorgang vorgesehen. Es kann jedoch in ObjectNode(und ArrayNode) gegossen werden , die Mutationen zulassen:

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

Für ein Array können Sie Folgendes verwenden:

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

4
versucht für einen numerischen Typ, in dem ich den Wert ändern muss. Ich habe diese Ausnahme: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

Sie müssen versuchen, "IntNode"
Mulya

6

Hinzufügen einer Antwort, da einige andere in den Kommentaren der akzeptierten Antwort positiv bewertet haben, erhalten sie diese Ausnahme, wenn sie versuchen, in ObjectNode umzuwandeln (ich selbst eingeschlossen):

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

Die Lösung besteht darin, den übergeordneten Knoten putabzurufen und den gesamten Knoten unabhängig vom ursprünglichen Knotentyp effektiv zu ersetzen.

Wenn Sie den Knoten unter Verwendung des vorhandenen Werts des Knotens "ändern" müssen:

  1. get der Wert / Array der JsonNode
  2. Nehmen Sie Ihre Änderung an diesem Wert / Array vor
  3. Rufen Sie putden Elternteil an.

Code, dessen Ziel das Ändern ist subfield, der der untergeordnete Knoten von NodeAund ist 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");

Credits:

Ich habe diese Inspiration von hier bekommen , dank wassgreen @


5

Die Antwort von @ Sharon-Ben-Asher ist in Ordnung.

Aber in meinem Fall muss ich für ein Array Folgendes verwenden:

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

4

Ich denke, Sie können einfach in ObjectNode umwandeln und die putMethode verwenden. So was

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



0

Nur um andere zu verstehen, die möglicherweise nicht das ganze Bild klarstellen, funktioniert der folgende Code für mich, um ein Feld zu finden und es dann zu aktualisieren

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");
    }
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.