【问题标题】:How to modify JsonNode in Java?如何在 Java 中修改 JsonNode?
【发布时间】:2015-09-08 22:22:34
【问题描述】:

我需要在 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
            }
        }
    }

最好的方法是什么?

【问题讨论】:

  • 您可以将 JsonNode 转换为 Java Map,例如resultMap = mapper.convertValue(aJsonNode, Map.class); 在 Map 中修改它,然后将该 Map 改回 JsonNode。只是说。

标签: java json jackson


【解决方案1】:

添加一个答案,因为其他一些人在已接受答案的 cmets 中投票,他们在尝试投射到 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");

学分:

我的灵感来自here,感谢wassgreen@

【讨论】:

    【解决方案2】:

    @Sharon-Ben-Asher 的答案还可以。

    但就我而言,对于我必须使用的数组:

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

    【讨论】:

      【解决方案3】:

      只是为了理解其他可能无法清楚了解整体情况的人,以下代码适用于我找到一个字段然后更新它

      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");
          }
      }
      

      【讨论】:

        【解决方案4】:

        我认为您可以转换为 ObjectNode 并使用 put 方法。像这样

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

        【讨论】:

          【解决方案5】:

          JsonNode 是不可变的,用于解析操作。但是,它可以转换为允许突变的ObjectNode(和ArrayNode):

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

          对于数组,可以使用:

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

          【讨论】:

          • 尝试了我需要更改值的数字类型。我得到了这个例外:Exception in thread "main" java.lang.ClassCastException: com.fasterxml.jackson.databind.node.IntNode cannot be cast to com.fasterxml.jackson.databind.node.ObjectNode
          • 你需要尝试“IntNode”
          • @balboa_21 更改整数并没有真正意义。这有点像我把 4 改成 9,然后世界上每个人都开始数 1、2、3、9、5、6、7、8。你要做的就是改变对象上的字段以包含不同的整数,因此您希望将对象作为 ObjectNode 更高,并操作相关字段。
          【解决方案6】:

          您需要获取ObjectNode 类型的对象才能设置值。 看看this

          【讨论】:

            猜你喜欢
            • 2017-05-12
            • 2023-02-22
            • 1970-01-01
            • 1970-01-01
            • 2023-03-19
            • 1970-01-01
            • 1970-01-01
            • 2014-12-18
            • 2021-02-11
            相关资源
            最近更新 更多