Iterando sobre una instancia de org.json.JSONObject

1. Introducción

En este tutorial, veremos un par de enfoques para iterar sobre un JSONObject , una representación JSON simple para Java.

Comenzaremos con una solución ingenua y luego veremos algo un poco más sólido.

2. Iterando a través de un JSONObject

Comencemos con el caso simple de iterar un JSON de pares nombre-valor:

{ "name": "Cake", "cakeId": "0001", "cakeShape": "Heart" }

Para esto, podemos simplemente iterar a través de las claves usando el método keys () :

void handleJSONObject(JSONObject jsonObject) { jsonObject.keys().forEachRemaining(key -> { Object value = jsonObject.get(key); logger.info("Key: {0}\tValue: {1}", key, value); } }

Y nuestra salida será:

Key: name Value: Cake Key: cakeId Value: 0001 Key: cakeShape Value: Heart

3. Atravesar un JSONObject

Pero digamos que tenemos una estructura más compleja:

{ "batters": [ { "type": "Regular", "id": "1001" }, { "type": "Chocolate", "id": "1002" }, { "type": "BlueBerry", "id": "1003" } ], "name": "Cake", "cakeId": "0001" }

¿Qué significa iterar a través de las claves en este caso?

Echemos un vistazo a lo que nos daría nuestro enfoque de claves ingenuas () :

Key: batters Value: [{"type":"Regular","id":"1001"},{"type":"Chocolate","id":"1002"}, {"type":"BlueBerry","id":"1003"}] Key: name Value: Cake Key: cakeId Value: 0001

Esto, quizás, no sea tan útil. Parece que lo que queremos en este caso no es iteración, sino recorrido.

Atravesar un JSONObject es diferente de recorrer en iteración el conjunto de claves de un JSONObject .

Para esto, también necesitamos verificar el tipo de valor. Imaginemos que hacemos esto en un método separado:

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

Entonces, nuestro enfoque sigue siendo bastante similar:

void handleJSONObject(JSONObject jsonObject) { jsonObject.keys().forEachRemaining(key -> { Object value = jsonObject.get(key); logger.info("Key: {0}", key); handleValue(value); }); }

Lo único es que debemos pensar en cómo manejar las matrices.

4. Atravesando un JSONArray

Intentemos mantener un enfoque similar al usar un iterador. Sin embargo, en lugar de llamar a keys () , llamaremos a iterator () :

void handleJSONArray(JSONArray jsonArray) { jsonArray.iterator().forEachRemaining(element -> { handleValue(element) }); }

Ahora, esta solución es limitante porque estamos combinando el recorrido con la acción que queremos realizar . Un enfoque común para separar los dos sería utilizar el patrón Visitante.

5. Conclusión

En este artículo, vimos una forma de iterar sobre un JSONObject para pares de nombre-valor simples, el problema asociado con estructuras complejas y una técnica transversal para resolverlo.

Por supuesto, este fue un método de recorrido de profundidad primero, pero podríamos hacer primero la amplitud de una manera similar.

El código completo del ejemplo está disponible en Github.