Як змінити 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, наприклад resultMap = mapper.convertValue(aJsonNode, Map.class);змінити її на карті, а потім змінити цю карту назад у JsonNode. Просто кажу.
MikeJRamsey56

Відповіді:


195

JsonNodeє незмінним і призначений для розбору. Однак це може бути передано в ObjectNodeArrayNode), які дозволяють мутації:

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

Рішення полягає в тому, щоб отримати «батьківський» вузол і виконати a 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 @


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");
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.