Come modificare JsonNode in Java?


109

Devo modificare il valore di un attributo JSON in Java, posso ottenere il valore correttamente ma non posso modificare il JSON.

ecco il codice qui sotto

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

Qual è il modo migliore per farlo?


1
È possibile convertire il JsonNode in una mappa Java, ad esempio resultMap = mapper.convertValue(aJsonNode, Map.class);modificarlo nella mappa e quindi cambiare quella mappa in un JsonNode. Sto solo dicendo.
MikeJRamsey56

Risposte:


195

JsonNodeè immutabile ed è destinato all'operazione di analisi. Tuttavia, può essere lanciato in ObjectNode(e ArrayNode) che consentono mutazioni:

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

Per un array, puoi usare:

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

4
provato per un tipo numerico in cui ho bisogno di cambiare il valore. Ho questa eccezione: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

Devi provare "IntNode"
mulya

6

Aggiungendo una risposta mentre alcuni altri hanno votato verso l'alto nei commenti della risposta accettata, ottengono questa eccezione quando tentano di eseguire il cast su ObjectNode (me compreso):

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

La soluzione è ottenere il nodo "genitore" ed eseguire un'operazione put, sostituendo efficacemente l'intero nodo, indipendentemente dal tipo di nodo originale.

Se è necessario "modificare" il nodo utilizzando il valore esistente del nodo:

  1. get il valore / matrice di JsonNode
  2. Esegui la tua modifica su quel valore / array
  3. Procedi a chiamare putil genitore.

Codice, dove l'obiettivo è modificare subfield, che è il nodo figlio di NodeAe 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");

Crediti:

Ho avuto questa ispirazione da qui , grazie a wassgreen @


5

La risposta di @ Sharon-Ben-Asher è ok.

Ma nel mio caso, per un array devo usare:

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

4

Penso che puoi semplicemente eseguire il cast su ObjectNode e usare il putmetodo. Come questo

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


2

È necessario ottenere l' ObjectNodeoggetto di tipo per impostare i valori. Dai un'occhiata a questo


0

Solo per motivi di comprensione di altri che potrebbero non avere l'intera immagine chiara, il seguente codice funziona per me per trovare un campo e quindi aggiornarlo

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");
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.