Bagaimana cara memodifikasi JsonNode di Java?

109

Saya perlu mengubah nilai atribut JSON di Java, saya bisa mendapatkan nilainya dengan benar tetapi saya tidak dapat memodifikasi JSON.

berikut adalah kode di bawah ini

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

Apa cara terbaik untuk melakukannya?

mstfdz.dll
sumber
1
Anda dapat mengubah JsonNode menjadi Java Map, misalnya resultMap = mapper.convertValue(aJsonNode, Map.class);memodifikasinya di Map dan kemudian mengubah Map itu kembali menjadi JsonNode. Hanya mengatakan.
MikeJRamsey56

Jawaban:

195

JsonNodetidak dapat diubah dan dimaksudkan untuk operasi penguraian. Namun, itu bisa dilemparkan ke ObjectNode(dan ArrayNode) yang memungkinkan mutasi:

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

Untuk sebuah array, Anda dapat menggunakan:

((ObjectNode)jsonNode).putArray("arrayName").add(object.ge‌​tValue());
Sharon Ben Asher
sumber
4
mencoba untuk tipe numerik di mana saya perlu mengubah nilainya. Saya mendapat pengecualian ini: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
Anda perlu mencoba "IntNode"
mulya
6

Menambahkan jawaban karena beberapa orang lain telah memberi suara positif di komentar jawaban yang diterima, mereka mendapatkan pengecualian ini ketika mencoba mentransmisikan ke ObjectNode (termasuk saya sendiri):

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

Solusinya adalah mendapatkan node 'induk', dan melakukan a put, secara efektif menggantikan seluruh node, terlepas dari jenis node aslinya.

Jika Anda perlu "mengubah" node menggunakan nilai node yang ada:

  1. get nilai / larik dari JsonNode
  2. Lakukan modifikasi Anda pada nilai / larik itu
  3. Lanjutkan untuk memanggil putorang tua.

Kode, yang tujuannya adalah untuk memodifikasi subfield, yang merupakan simpul anak dari NodeAdan 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");

Kredit:

Saya mendapat inspirasi ini dari sini , terima kasih kepada wassgreen @

matrixanomaly.dll
sumber
5

Jawaban @ Sharon-Ben-Asher tidak apa-apa.

Tetapi dalam kasus saya, untuk array saya harus menggunakan:

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

Saya pikir Anda bisa melemparkan ke ObjectNode dan menggunakan putmetode. Seperti ini

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

Xdsasdf
sumber
2

Anda perlu mendapatkan ObjectNodetipe objek untuk mengatur nilai. Coba lihat ini

Eugen Halca
sumber
0

Hanya demi pemahaman orang lain yang mungkin tidak mendapatkan gambaran keseluruhan, kode berikut jelas berfungsi bagi saya untuk menemukan bidang dan kemudian memperbaruinya

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
sumber