Java에서 JsonNode를 수정하는 방법은 무엇입니까?


109

Java에서 JSON 속성 값을 변경해야합니다. 값을 제대로 가져올 수 있지만 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 맵으로 변환 할 수 있습니다. 예를 들어 맵에서 resultMap = mapper.convertValue(aJsonNode, Map.class);수정 한 다음 해당 맵을 다시 JsonNode로 변경할 수 있습니다. 그냥 말해.
MikeJRamsey56

답변:


195

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의 하위 노드 인 을 수정하는 것이 목표 인 코드 :NodeANode1

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 @ 덕분에 여기서 영감을 얻었습니다.


5

@ Sharon-Ben-Asher 대답은 괜찮습니다.

하지만 제 경우에는 배열을 사용해야합니다.

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

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.