This is what I am trying to do. lets say I have 2 json inputs.
First
{"testArr":[{"name":"name1"},{"name":"name2"}]}
Second
{"testArr":[{"name":"name1Changed"}]}
And I have classes
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);
}
}
So after this one I am getting
{"testArr":[{"name":"name1Changed"}]}
where I want to get
{"testArr":[{"name":"name1Changed"},{"name":"name2"}]}
Please let me know if I am missing something from Jackson or there are no such functionality and I would need to write my own.
Since there are no straight conversation to do what i wanted here is what i wrote for json nodes to do the same thing. Two functions to merger/overwrite nodes and merge/overwriteArray. This works by passing 2 json Nodes hope that will help if anyone are looking for similar things
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));
}
}
}
Your best bet is to read both document as
JsonNode
s, then traverse and update first document using logic you have in mind. Unfortunately there are many possible ways in which one might want to merge -- for example, in case of JSON arrays, should one or both be chosen; or should they be concatened; or should the entries be overridden by index (which is what you want) -- so Jackson does not have functionality for such processing.