1. Introduction
In this tutorial, we'll look at a couple of approaches for iterating over a JSONObject, a simple JSON representation for Java.
We'll start with a naive solution and then look at something a little more robust.
2. Iterating Through a JSONObject
Let's start with the simple case of iterating a JSON of name-value pairs:
{
"name": "Cake",
"cakeId": "0001",
"cakeShape": "Heart"
}
For this, we can simply iterate through the keys using the keys() method:
void handleJSONObject(JSONObject jsonObject) {
jsonObject.keys().forEachRemaining(key -> {
Object value = jsonObject.get(key);
logger.info("Key: {0}\tValue: {1}", key, value);
}
}
And our output will be:
Key: name Value: Cake
Key: cakeId Value: 0001
Key: cakeShape Value: Heart
3. Traversing Through a JSONObject
But let's say that we have a more complex structure:
{
"batters": [
{
"type": "Regular",
"id": "1001"
},
{
"type": "Chocolate",
"id": "1002"
},
{
"type": "BlueBerry",
"id": "1003"
}
],
"name": "Cake",
"cakeId": "0001"
}
What does iterating through the keys mean in this case?
Let's take a look at what our naive keys() approach would give us:
Key: batters Value: [{"type":"Regular","id":"1001"},{"type":"Chocolate","id":"1002"},
{"type":"BlueBerry","id":"1003"}]
Key: name Value: Cake
Key: cakeId Value: 0001
This, perhaps, isn't quite as helpful. It seems like what we want in this case is not iteration, but instead traversal.
Traversing through a JSONObject is different from iterating through a JSONObject‘s key set.
For this, we actually need to check the value type, too. Let imagine we do this in a separate method:
void handleValue(Object value) {
if (value instanceof JSONObject) {
handleJSONObject((JSONObject) value);
} else if (value instanceof JSONArray) {
handleJSONArray((JSONArray) value);
} else {
logger.info("Value: {0}", value);
}
}
Then, our approach is still fairly similar:
void handleJSONObject(JSONObject jsonObject) {
jsonObject.keys().forEachRemaining(key -> {
Object value = jsonObject.get(key);
logger.info("Key: {0}", key);
handleValue(value);
});
}
The only thing is that we need to think about how to handle arrays.
4. Traversing Through a JSONArray
Let's try and keep a similar approach of using an iterator. Instead of calling keys(), though, we'll call iterator():
void handleJSONArray(JSONArray jsonArray) {
jsonArray.iterator().forEachRemaining(element -> {
handleValue(element)
});
}
Now, this solution is limiting because we are combining traversal with the action we want to take. A common approach to separating the two would be using the Visitor pattern.
5. Conclusion
In this article, we saw a way to iterate over a JSONObject for simple name-value pairs, the problem associated with complex structures, and a traversal technique to solve it.
Of course, this was a depth-first traversal method, but we could do breadth-first in a similar way.
The complete code for the example is available over on Github.
Course – LS (cat=JSON/Jackson) res – REST with Spring (eBook) (everywhere)