Ejemplos JSON y Java con Gson

De ChuWiki

Gson es una librería java de google que facilita la conversión de clases java a cadenas JSON y viceversa, así como generar y analizar cadenas JSON sin necesidad de tener clases Java asociadas. Veamos algunos ejemplos que tienes al completo en JsonExamples


Preparar el entorno[editar]

Primero tienes que bajarte la librería gson y añadir el jar correspondiente en tu IDE favorito.


Teniendo beans Java preparados[editar]

toJson[editar]

Imagina que tienes un bean java como el siguiente (fíjate que no es un bean estrictamente hablando, puesto que no tiene getter, setter ni constructor por defecto, podemos ponerlos, pero Gson no los necesita).

package com.chuidiang.ejemplos.json;

import java.util.Date;

public class Data {

   public Data(String aString, int aInt, Integer aInteger, Date aDate) {
      super();
      this.aString = aString;
      this.aInt = aInt;
      this.aInteger = aInteger;
      this.aDate = aDate;
   }

   private String aString = "a String";
   private int aInt = 22;
   private Integer aInteger = new Integer(11);
   private Date aDate = new Date();

   @Override
   public String toString() {
      return "Data [aString=" + aString + ", aInt=" + aInt + ", aInteger="
            + aInteger + ", aDate=" + aDate + "]";
   }

}

y queremos convertir este bean a cadena JSON u obtener este bean a partir de cadenas JSON. Con Gson es fácil, solo necesitamos una instacia de la clase Gson y usar sus método toJson() y fromJson().


Gson gson = new Gson();

Si tenemos el bean instanciado y queremos convertirlo a una cadena JSON, el código es este

String json = gson.toJson(new Data("string", 10, null, new Date()));

que dará algo como

{"aString":"string","aInt":10,"aDate":"Feb 26, 2014 8:53:41 PM"}

Si tenemos una lista o un array de beans, la forma es igual de fácil

Data [] dataArray = new Data[3];
for (int i = 0; i < dataArray.length; i++) {
   dataArray[i] = new Data("a String " + i, i, new Integer(i + 2), new Date());
}

String json = gson.toJson(dataArray);

o bien, con una lista

List<Data> dataList = new LinkedList<>();
for (int i=0;i<3;i++) {
   dataList.add(new Data("a String " + i, i, new Integer(i + 2), new Date()));
}

String json = gson.toJson(dataList);

En ambos casos, obtendremos algo como esto

[{"aString":"a String 0","aInt":0,"aInteger":2,"aDate":"Feb 26, 2014 8:53:41 PM"}, 
 {"aString":"a String 1","aInt":1,"aInteger":3,"aDate":"Feb 26, 2014 8:53:41 PM"},
 {"aString":"a String 2","aInt":2,"aInteger":4,"aDate":"Feb 26, 2014 8:53:41 PM"}]

Para el formateo de fechas, podemos generar una instancia especial de Gson con el formato que queramos para las fechas, de esta forma

Gson gson = new GsonBuilder().setDateFormat("dd/MM/yy HH:mm:ss").create();
String json = gson.toJson(new Date());

que daría

"26/02/14 20:53:41"

fromJson[editar]

De forma similar, teniendo la cadena JSON, podemos obtener los beans correspondientes

String json = "{'aString':'from Parsed String','aInt':33,'aInteger':null,'aDate':'Feb 26, 2014 7:35:23 PM'}";

Data parsedData = gson.fromJson(json, Data.class);

símplemente debemos indicar como segundo parámetro qué clase queremos obtener. La conversión no falla, si en la cadena JSON hay más parámetros de la cuenta, se ignoran, si el bean tiene más atributos, no se rellenan.


Sin bean Java[editar]

Si no tenemos un bean java, quizás porque estamos analizando una cadena JSON que hemos obtenido de algún sitio o debemos generarla con datos recogidos de algún otro sitio, Gson nos ofrece las clases JsonPrimitive, JsonObject y JsonArray, todas ellas implementando la interfaz JsonElemnt


Construir cadena JSON[editar]

Para el caso de datos primitivos (boolean, String ...)

JsonPrimitive primitive = new JsonPrimitive(Boolean.TRUE);
String json = primitive.toString();

Devolvería un String con

true

Para un Objeto JSON, podemos hacer algo así

JsonObject object = new JsonObject();
object.addProperty("name", "Juan");
object.addProperty("age", 22);
object.addProperty("birthday", new Date().toString());

String json = object.toString();

que devolvería una cadena así

{"name":"Juan","age":22,"birthday":"Wed Feb 26 21:39:10 CET 2014"}

Por supuesto, podemos añadir addProperty("key", JSonElement) para añadir otro JSonObject o JsonArray dentro de nuestro objeto.

Para arrays, podemos hacer un código como este

JsonArray array = new JsonArray();
array.add(jsonElement1); // JsonPrimitive, JsonObject o JsonArray
array.add(jsonElement2);

String json = array.toString());

que daría un String del estilo

[{"name":"Juan","age":22,"birthday":"Wed Feb 26 21:39:10 CET 2014"},
 {"name":"Juan","age":22,"birthday":"Wed Feb 26 21:39:10 CET 2014"}]


Parsear una cadena JSON[editar]

Si tenemos la cadena JSON, podemos analizarla usando estos objetos JsonElement. Por ejemplo, si la cadena tiene una primitiva

JsonParser parser = new JsonParser();
      
JsonElement elementPimitive = parser.parse("true");
if (elementPimitive.isJsonPrimitive() &&
    elementPimitive.getAsJsonPrimitive().isBoolean()){
    boolean value = elementPimitive.getAsBoolean();
}

Instanciamos un JsonParser. El método parse() de de JsonParser devuevle un JsonElement. Este elemento tiene métodos para interrogar de qué tipos es, como isJsonPrimitive() y métodos para obtenerlo como ese tipo concreto, como getAsJsonPrimitive() y una vez indentificado exactamente de qué tipo es el valor que hay dentro, métodos para obtener dicho valor, como getAsBoolean()

Con una cadena tipo JsonObject, omitimos aquí los if para saber exactamente el tipo de JsonElement que es, el código sería así

JsonElement elementObject = parser.parse("{'name':'Juan','age':22,'birthday':'Wed Feb 26 20:39:53 CET 2014'}");
String name = elementObject.getAsJsonObject().get("name").getAsString());

que nos devolvería el name

Juan

Finalmente, para arrays, podemos hacer así

JsonElement arrayElement = parser.parse(
   "[{'name':'Juan','age':22,'birthday':'Wed Feb 26 20:44:23 CET 2014'},"
   + "{'name':'Juan','age':22,'birthday':'Wed Feb 26 20:39:53 CET 2014'}]");
System.out.println(arrayElement.getAsJsonArray().size());
int age = arrayElement.getAsJsonArray().get(0).getAsJsonObject().get("age").getAsInt();

Nuevamente nos hemos saltado las comprobaciones. Esto nos devolverá el tamaño del array y la edad del primer elemento.