Jak zmodyfikować JsonNode w Javie?

109

Muszę zmienić wartość atrybutu JSON w Javie, mogę poprawnie uzyskać wartość, ale nie mogę zmodyfikować JSON.

oto kod poniżej

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

Jaki jest najlepszy sposób, aby to zrobić?

mstfdz
źródło
1
Możesz przekonwertować JsonNode na mapę Java, np. resultMap = mapper.convertValue(aJsonNode, Map.class);Zmodyfikować ją w mapie, a następnie zmienić tę mapę z powrotem na JsonNode. Tylko mówię.
MikeJRamsey56

Odpowiedzi:

195

JsonNodejest niezmienna i jest przeznaczona do operacji analizowania. Można go jednak rzucić na ObjectNode(i ArrayNode), które pozwalają na mutacje:

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

W przypadku tablicy możesz użyć:

((ObjectNode)jsonNode).putArray("arrayName").add(object.ge‌​tValue());
Sharon Ben Asher
źródło
4
próbował dla typu liczbowego, w którym muszę zmienić wartość. Mam ten wyjątek: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
Musisz wypróbować „IntNode”
mulya
6

Dodając odpowiedź, ponieważ niektórzy inni głosowali za w komentarzach do zaakceptowanej odpowiedzi, dostają ten wyjątek podczas próby rzutowania do ObjectNode (włącznie ze mną):

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

Rozwiązaniem jest pobranie węzła „nadrzędnego” i wykonanie putefektywnej zamiany całego węzła, niezależnie od oryginalnego typu węzła.

Jeśli chcesz „zmodyfikować” węzeł przy użyciu istniejącej wartości węzła:

  1. get wartość / tablica pliku JsonNode
  2. Dokonaj modyfikacji na tej wartości / tablicy
  3. Kontynuuj, aby zadzwonić putdo rodzica.

Kod, którego celem jest modyfikacja subfield, który jest węzłem potomnym NodeAi 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");

Kredyty:

Stąd czerpałem inspirację dzięki wassgreen @

matrixanomalia
źródło
5

Odpowiedź @ Sharon-Ben-Asher jest w porządku.

Ale w moim przypadku dla tablicy muszę użyć:

((ArrayNode) jsonNode).add("value");
Alejandro
źródło
4

Myślę, że możesz po prostu przesłać do ObjectNode i użyć putmetody. Lubię to

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

Xdsasdf
źródło
2

Musisz pobrać ObjectNodeobiekt typu, aby ustawić wartości. Spójrz na to

Eugen Halca
źródło
0

Tylko ze względu na zrozumienie innych, którzy mogą nie uzyskać pełnego obrazu, następujący kod działa dla mnie, aby znaleźć pole, a następnie je zaktualizować

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");
    }
}
Mubaszar
źródło