¿Cómo modificar JsonNode en Java?

109

Necesito cambiar el valor de un atributo JSON en Java, puedo obtener el valor correctamente pero no pude modificar el JSON.

aquí está el código a continuación

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

¿Cuál es la mejor manera de hacer esto?

mstfdz
fuente
1
Puede convertir el JsonNode en un mapa de Java, por ejemplo, resultMap = mapper.convertValue(aJsonNode, Map.class);modificarlo en el mapa y luego cambiar ese mapa de nuevo a un JsonNode. Solo digo.
MikeJRamsey56

Respuestas:

195

JsonNodees inmutable y está diseñado para la operación de análisis. Sin embargo, se puede convertir en ObjectNode(y ArrayNode) que permitan mutaciones:

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

Para una matriz, puede usar:

((ObjectNode)jsonNode).putArray("arrayName").add(object.ge‌​tValue());
Sharon Ben Asher
fuente
4
Intenté un tipo numérico en el que necesito cambiar el valor. Tengo esta excepción: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
Debes probar "IntNode"
mulya
6

Al agregar una respuesta, ya que algunos otros han votado a favor en los comentarios de la respuesta aceptada, obtienen esta excepción al intentar transmitir a ObjectNode (incluido yo mismo):

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

La solución es obtener el nodo 'principal' y realizar un putreemplazo efectivo de todo el nodo, independientemente del tipo de nodo original.

Si necesita "modificar" el nodo utilizando el valor existente del nodo:

  1. get el valor / matriz del JsonNode
  2. Realice su modificación en ese valor / matriz
  3. Proceda a llamar puta los padres.

Código, donde el objetivo es modificar subfield, que es el nodo hijo de NodeAy 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");

Créditos:

Obtuve esta inspiración de aquí , gracias a wassgreen @

anomalía de la matriz
fuente
5

La respuesta de @ Sharon-Ben-Asher está bien.

Pero en mi caso, para una matriz tengo que usar:

((ArrayNode) jsonNode).add("value");
Alejandro
fuente
4

Creo que puedes simplemente convertir a ObjectNode y usar el putmétodo. Me gusta esto

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

Xdsasdf
fuente
2

Necesita obtener el ObjectNodetipo de objeto para establecer valores. Echa un vistazo a esto

Eugen Halca
fuente
0

Solo por el bien de la comprensión de otros que pueden no tener la imagen completa clara, el siguiente código me funciona para encontrar un campo y luego actualizarlo

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
fuente