2

这就是我想要做的。假设我有 2 个 json 输入。

第一的

{"testArr":[{"name":"name1"},{"name":"name2"}]}

第二

{"testArr":[{"name":"name1Changed"}]}

我有课

class test{
 public String name;
}

class runner{
  public ArrayList<test> testArr;
  public String firstJson;
  public String secondJson;

  public void runProj(){
    ObjectMapper mapper = new ObjectMapper();
    //This one is correct works just fine
    testArr = mapper.readValue(firstJson, ITBTeam.class);

    //Now I want to update just value of first element of array and 
    //tryed to use this function but this one will trim my array
     mapper.readerForUpdating(testArr).readValue(secondJson);
  }

}

所以在这个之后我得到了

{"testArr":[{"name":"name1Changed"}]}

我想去哪里

{"testArr":[{"name":"name1Changed"},{"name":"name2"}]}

请让我知道我是否遗漏了杰克逊的某些东西或者没有这样的功能,我需要自己编写。

由于没有直接的对话来做我想要的,所以我为 json 节点写的东西做同样的事情。合并/覆盖节点和合并/覆盖数组的两个函数。这通过传递 2 个 json 节点来工作,希望如果有人正在寻找类似的东西会有所帮助

 public static JsonNode mergeNode(JsonNode mainNode, JsonNode updateNode) {
    Iterator<String> fieldNames = updateNode.fieldNames();
    while (fieldNames.hasNext()) {

        String fieldName = fieldNames.next();
        JsonNode jsonNode = mainNode.get(fieldName);
        // if field exists and is an embedded object
        if (null != jsonNode && (jsonNode.isObject())) {
            mergeNode(jsonNode, updateNode.get(fieldName));
            // if field exists and is an embedded array
        } else if (null != jsonNode && (jsonNode.isArray())) {
            mergeArray(jsonNode, updateNode.get(fieldName));
        } else {
            // Overwrite field node               
            ((ObjectNode) mainNode).set(fieldName, updateNode.get(fieldName));
        }
    }
    return mainNode;
}

public static void mergeArray(JsonNode mainNode, JsonNode updateNode) {
    //Loops over array and adds items if they dont exist 
    //or updates existing value if it is not an object
    for (int i = 0; i < updateNode.size(); i++) {
        JsonNode jsonNode = mainNode.get(i);
        if (null != jsonNode && jsonNode.isObject()) {
            mergeNode(jsonNode, updateNode.get(i));
        } else if (null != jsonNode && (jsonNode.isArray())) {
            mergeArray(jsonNode, updateNode.get(i));
        } else if (null == jsonNode) {
            ((ArrayNode) mainNode).add(updateNode.get(i));
        } else {
            ((ArrayNode) mainNode).set(i, updateNode.get(i));
        }
    }       
}
4

2 回答 2

1

您最好的选择是将两个文档都读取为JsonNodes,然后使用您想到的逻辑遍历和更新第一个文档。不幸的是,有许多可能的合并方式——例如,在 JSON 数组的情况下,应该选择一种或两种方式;还是应该将它们连接起来;或者条目是否应该被索引覆盖(这是你想要的)——所以杰克逊没有这种处理的功能。

于 2014-12-31T00:38:17.530 回答
1

现在您可以使用 JSON-Patch https://github.com/fge/json-patch来合并两个 JSON 对象/节点

    // With Jackson
    final JsonMergePatch patch = mapper.readValue(in, JsonMergePatch.class);
    // With a JsonNode
    final JsonMergePatch patch = JsonMergePatch.fromJson(node);

    // orig is also a JsonNode
    final JsonNode patched = patch.apply(orig);
于 2015-07-06T11:44:08.007 回答