จะแก้ไข JsonNode ใน Java ได้อย่างไร?


109

ฉันต้องการเปลี่ยนค่าของแอตทริบิวต์ JSON ใน Java ฉันสามารถรับค่าได้อย่างถูกต้อง แต่ฉันไม่สามารถแก้ไข JSON ได้

นี่คือรหัสด้านล่าง

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

วิธีที่ดีที่สุดในการทำคืออะไร?


1
คุณสามารถแปลง JsonNode เป็น Java Map เช่นresultMap = mapper.convertValue(aJsonNode, Map.class);แก้ไขในแผนที่จากนั้นเปลี่ยน Map นั้นกลับเป็น JsonNode แค่พูด.
MikeJRamsey56

คำตอบ:


196

JsonNodeไม่เปลี่ยนรูปและมีไว้สำหรับการดำเนินการแยกวิเคราะห์ อย่างไรก็ตามสามารถแปลงเป็นObjectNode(และArrayNode) ที่อนุญาตให้เกิดการกลายพันธุ์:

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

สำหรับอาร์เรย์คุณสามารถใช้:

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

4
พยายามหาประเภทตัวเลขที่ฉันต้องการเปลี่ยนค่า ฉันได้รับข้อยกเว้นนี้: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

คุณต้องลอง "IntNode"
mulya

6

การเพิ่มคำตอบเนื่องจากบางคนได้เพิ่มคะแนนในความคิดเห็นของคำตอบที่ยอมรับพวกเขาได้รับข้อยกเว้นนี้เมื่อพยายามส่งไปยัง ObjectNode (รวมตัวเองด้วย):

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

วิธีแก้ปัญหาคือการรับโหนด 'หลัก' และดำเนินการputแทนที่โหนดทั้งหมดอย่างมีประสิทธิภาพโดยไม่คำนึงถึงประเภทโหนดดั้งเดิม

หากคุณต้องการ "แก้ไข" โหนดโดยใช้ค่าที่มีอยู่ของโหนด:

  1. get ค่า / อาร์เรย์ของ JsonNode
  2. ทำการแก้ไขของคุณกับค่า / อาร์เรย์นั้น
  3. ดำเนินการโทรหาputผู้ปกครอง

รหัสที่เป้าหมายคือการแก้ไขsubfieldซึ่งเป็นโหนดลูกของNodeAและ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");

เครดิต:

ฉันได้รับแรงบันดาลใจจากที่นี่ขอบคุณwassgreen @



4

ฉันคิดว่าคุณสามารถส่งไปยัง ObjectNode และใช้putวิธีการ แบบนี้

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



0

เพียงเพื่อความเข้าใจของผู้อื่นที่อาจไม่ได้รับภาพรวมที่ชัดเจนรหัสต่อไปนี้ทำงานให้ฉันค้นหาฟิลด์แล้วอัปเดต

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");
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.