Reputation: 103
Apologies, Google tells me there are many similar questions to this already asked on Stack Overflow but I'm struggling to find an answer that works for my situation.
I have a Java application that is using JsonNode for the first time (previously mapped to Java classes but that isn't an option on this occasion).
We retrieve a JSON object from a third party, example JSON below:.
[
{
"id": "123",
"name": "name",
"dateCreated": "2023-08-03T09:38:21.221Z",
"queues": {
"wait": [
{
"criteria": [
{
"type": "s",
"threshold": 20
}
],
"groups": [
{
"id": "123",
"name": "Group 1"
}
]
},
{
"criteria": [
{
"type": "s",
"threshold": 10
}
]
},
{
"criteria": [
{
"type": "s",
"threshold": 30
}
]
},
{
"criteria": [
{
"type": "s",
"threshold": 2
}
]
}
]
}
}
]
I need to update each 'threshold' value in the wait array and then return the JsonNode to another service.
It's very important I maintain the order of each index in the 'wait' array. Also I can only guarantee that 'threshold' will be within a nested 'criteria' array, I cannot guarantee other values won't be present e.g. the 'groups' array in the example above, but it is important that all fields are maintained and none lost.
I have found out online that JsonNode is immutable and you need to cast to ObjectArray to get the put/set methods, however I can't see how these method work for nested values e.g. I can use it to update 'name' but I am struggling to use it to update anything inside 'queues'.
I have seen some posts regarding ArrayNode but all examples I find regards to replacing an entire array and I only want to update single values inside the array.
Any help is much appreciated.
Upvotes: 0
Views: 429
Reputation: 539
ObjectNode
contains put() method, which can change the value of the node. You have to cast the JsonNode
into ObjectNode
.
I could accomplish this using the following code. I am assuming that all the threshold values will be set to a fixed value. In my case I'm assuming it is 50:
for (JsonNode node : jsonNode) {
JsonNode waitNode = node.path("queues").path("wait");
if (waitNode.isArray()) {
for (JsonNode item : waitNode) {
((ObjectNode) item.path("criteria").get(0)).put("threshold", 50);
}
}
}
// Print updated JSON node using jsonNode.toPrettyString()
System.out.println("JSON after Node edit: " + jsonNode.toPrettyString());
Upvotes: 1
Reputation: 6985
ObjectNode
has methods set()
and put()
, which mutate the node. You just need to reach that node, cast it and set the value. Example:
public class SoMain {
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(json);
for (JsonNode node1 : root) {
for (JsonNode node2 : node1.get("queues").get("wait")) {
for (JsonNode criteriaNode : node2.get("criteria")) {
// ((ObjectNode) criteriaNode).set("threshold", new IntNode(111));
((ObjectNode) criteriaNode).put("threshold",111);
}
}
}
System.out.println(root);
}
}
Upvotes: 1