Convertir cadena JSON a objetos nativos de Java
JSON se ha convertido en el formato estándar para el intercambio de datos entre sitios web; dejando atrás a XML por su complejidad y dificultad para ser leída por las personas.
Por ello es que hoy vamos a ver cómo parsear o decodificar una cadena JSON dentro de un objeto nativo de Java, sin importar si es un arreglo u objeto, anidado o no anidado.
Esto será un poco complejo ya que Java es un lenguaje fuertemente tipado y no podemos hacerlo tan simple como en JavaScript.
Librería y configuración del proyecto
Recomiendo Instalar NetBeans con Java (lo recomiendo, aunque no es forzoso) y luego descarga la librería de JSON en este enlace. Cuando entres a la página haz click en bundle para obtener el JAR.
Una vez que lo hayas descargado debes incluirlo en tu proyecto, si usas NetBeans mira cómo hacerlo aquí. El punto es que tienes que incluir el JAR dentro de tu proyecto para que puedas compilar correctamente.
Trabajar con JSON y Java
Para cada objeto de JSON que vamos a decodificar se recomienda tener una clase. Igualmente se pueden obtener los datos por separado, pero el paradigma es mejor si abstraemos todo en una clase.
Parsear un objeto JSON a una clase de Java
Comencemos con lo más simple y es decodificar una cadena de JSON que representa un objeto usando Java. En este caso la cadena JSON es así:
{"nombre":"Maggie","edad":3}
Como representa a una mascota, voy a crear la clase Mascota y queda así:
public class Mascota {
private String nombre;
private int edad;
public Mascota(String nombre, int edad) {
this.nombre = nombre;
this.edad = edad;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public int getEdad() {
return edad;
}
public void setEdad(int edad) {
this.edad = edad;
}
public void ladrar() {
System.out.println(String.format("¡Guau! me llamo %s y tengo %d años", nombre, edad));
}
}
Una vez definido todo eso, veamos cómo decodificar la cadena dentro de la clase de Java y es así:
// En tus imports coloca sin comentar:
// import org.json.JSONObject;
// Poner el JSON en un String para demostrar
String cadenaJson = "{\"nombre\":\"Maggie\",\"edad\":3}";
// Crear un nuevo objeto JSON
JSONObject objetoJson = new JSONObject(cadenaJson);
// Y ahora podemos acceder a través de getTipoDeDato
int edad = objetoJson.getInt("edad");
String nombre = objetoJson.getString("nombre");
// Luego de eso podemos crear la clase y obtener los beneficios
// de la POO o usar los datos como nos plazca
Mascota mascota = new Mascota(nombre, edad);
// Podemos hacer lo que sea con el objeto
mascota.ladrar();
Se crea un objeto “genérico” de tipo JSONObject y para obtener determinado valor en determinada clave usamos objetoJson.getTipoDeDato("clave")
.
Más tarde podemos crear un objeto a partir de ello o usar los datos primitivos por separado.
Objetos y arreglos dentro de otros objetos
Cabe mencionar que si el objeto tiene otros objetos dentro de él, se puede llamar a objetoJson.getJSONObject("clave")
al igual que si tuviera un arreglo se llamaría a objetoJson.getJSONArray("clave")
.
Saber si el objeto tiene un dato en determinada clave
Como JSON no tiene una estructura definida que nos garantice que siempre tendremos los datos, una manera de comprobar si el objeto tiene una clave vendría de maravilla.
Es por eso que el objeto de tipo JSONObject
tiene el método has
, que recibe una clave como cadena y devuelve un booleano.
boolean tieneClave = objetoJson.has("clave");
Con eso comprobamos si tiene algo en esa clave, ya sea un objeto, dato primitivo o arreglo.
Parsear un arreglo de objetos JSON
Arriba vimos cómo parsear un objeto, pero ahora vamos a ver cómo decodificar un arreglo de objetos. Para ello se crea igualmente un objeto pero ahora de tipo JSONArray y se itera dentro de un ciclo for con un objeto de tipo JSONObject.
Nota: importa JSONArray con import org.json.JSONArray;
La cadena JSON que vamos a parsear será esta:
[{"nombre":"Maggie","edad":3},{"nombre":"Snowball","edad":1},{"nombre":"Bichi","edad":1},{"nombre":"Meca","edad":5}]
Como se observa, es un arreglo de Mascotas. Para parsear usamos el siguiente código:
String cadenaJson = "[{\"nombre\":\"Maggie\",\"edad\":3},{\"nombre\":\"Snowball\",\"edad\":1},{\"nombre\":\"Bichi\",\"edad\":1},{\"nombre\":\"Meca\",\"edad\":5}]";
JSONArray arregloJson = new JSONArray(cadenaJson);
// Nota: creamos la lista para ejemplos ilustrativos, no es necesaria
ArrayList<Mascota> mascotas = new ArrayList<>();
// Iterar
for (int indice = 0; indice < arregloJson.length(); indice++) {
// Obtener objeto a través del índice
JSONObject posibleMascota = arregloJson.getJSONObject(indice);
// Acceder como accedíamos al jsonObject
int edad = posibleMascota.getInt("edad");
String nombre = posibleMascota.getString("nombre");
// Luego de eso podemos crear la clase y obtener los beneficios
// de la POO o usar los datos como nos plazca
Mascota mascota = new Mascota(nombre, edad);
// Podemos hacer lo que sea con el objeto
mascota.ladrar();
// Agregar a la lista, solo para ilustrar
mascotas.add(mascota);
}
// Aquí hacer lo que sea con la lista de mascotas
En el código creamos un nuevo JSONArray
con la cadena JSON. Lo iteramos con un ciclo for y obtenemos un objeto de tipo JSONObject
con el que podemos trabajar como en el ejemplo anterior.
En cada iteración se agrega una mascota a la lista de mascotas; como lo digo en el código, esto no es necesario, solamente muestro lo que se puede alcanzar o hacer.
Por cierto, no siempre tendremos arreglos de objetos, por ello es que igualmente se puede llamar a getInt
, getDouble
y todo lo que se puede hacer con los objetos; incluso podemos llamar a getJSONArray
. Eso sí, para acceder se usan índices numéricos y no claves como cadena.
Conclusión
Así es como se decodifican cadenas JSON con Java. En este caso las cadenas JSON son puestas directamente en el código pero bien podrían ser obtenidas de un servicio web. Como lo dije, se trabaja con los objetos base de tipo JSONArray y JSONObject, para a partir de ellos obtener otros tipos de datos.
Los métodos que tienen son (bueno, los más importantes):
- getBoolean: obtener un booleano
- getDouble: tipo de dato double
- getLong: tipo de dato long
- getEnum: un enum
- getBigDecimal: obtener un objeto de tipo BigDecimal
- getString: obtener una cadena
- getJSONArray: obtener un arreglo
- getJSONObject: obtener un objeto
- has: booleano que dice si tiene un dato en determinada clave
Si tienes dudas puedes dejarlas en los comentarios. Aprende más sobre Java aquí.
Pingback: Codificar JSON en Java usando org.json - Parzibyte's blog
Pingback: Petición HTTP GET en Java para consumir HTML o JSON - Parzibyte's blog