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?

mstfdz
quelle
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());
Sharon Ben Asher
quelle
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 @

Matrixanomalie
quelle
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");
Alejandro
quelle
4

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

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

Xdsasdf
quelle
2

Sie müssen Typobjekt ObjectNodeabrufen, um Werte festzulegen. Schauen Sie sich auf diese

Eugen Halca
quelle
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");
    }
}
Mubashar
quelle