Procesando JSON con la librería Gson

 

GSON es una librería de código abierto creada por Google que permite serializar objetos Java para convertirlos en un String. Su uso más frecuente es para convertir un objeto en su representación JSON y a la inversa.

La gran ventaja de esta librería es que puede ser usada sobre objetos de cualquier tipo de clases, incluso clases preexistentes que no has creado. Esto es posible al no ser necesario introducir código en las clases para que sean serializadas.

El código necesario es muy reducido, como se muestra a continuación:

  private ArrayList<Puntuacion> puntuaciones=new ArrayList<>();   
private Gson gson = new Gson();
private Type type = new TypeToken<List<Puntuacion>>() {}.getType();

// Convertimos la colección de datos a un String JSON
String string = gson.toJson(puntuaciones, type);

// Convertimos un String JSON a una la colección de datos
puntuaciones = gson.fromJson(string, type);

 

En este código puntuaciones contiene una colección (List) de elementos de tipo Puntuacion. Para representar estos datos en JSON vamos a necesitar un objeto Gson y otro Type. Este último representa el tipo de datos con el que trabajamos. En la variable string se almacenará el contenido de puntuaciones en representación JSON. En la siguiente línea se hace el proceso inverso.

La librería no solo permite transformar los datos en JSON, también podemos personalizar la serialización de los datos según las necesidades del programador. También permite excluir algunos atributos para que sean incluidos en la representación JSON.

Ejercicio: Guardar puntuaciones en JSON con la librería Gson.

1.     Crea la clase Puntuacion con el  siguiente código:

 public class Puntuacion {
    private int puntos;
    private String nombre;
    private long fecha;

    public Puntuacion(int puntos, String nombre, long fecha) {
        this.puntos = puntos;
        this.nombre = nombre;
        this.fecha = fecha;
    }
}

2.      Sitúate al final de la clase y selecciona Code > Generate > Getter and Setter. Selecciona todos los atributos y pulsa OK.

3.      Añade al fichero Gradle Scripts/Bulid.gradle (Module:app) la dependencia:

 dependencies {
    …
    compile 'com.google.code.gson:gson:2.6.2'
}

4.     Crea la clase AlmacenPuntuacionesGSon con el siguiente código:

public class AlmacenPuntuacionesGSon implements AlmacenPuntuaciones {
   private String string; //Almacena puntuaciones en formato JSON
   private Gson gson = new Gson();
   private Type type = new TypeToken<List<Puntuacion>>() {}.getType();

   public AlmacenPuntuacionesGSon() {
      guardarPuntuacion(45000,"Mi nombre", System.currentTimeMillis());
      guardarPuntuacion(31000,"Otro nombre", System.currentTimeMillis());
   }

   @Override
   public void guardarPuntuacion(int puntos, String nombre, long fecha) {
      //string = leerString();
      ArrayList<Puntuacion> puntuaciones;
      if (string == null) {
         puntuaciones = new ArrayList<>();
      } else {
         puntuaciones = gson.fromJson(string, type);
      }
      puntuaciones.add(new Puntuacion(puntos, nombre, fecha));
      string = gson.toJson(puntuaciones, type);
      //guardarString(string);
   }

   @Override
   public Vector<String> listaPuntuaciones(int cantidad) {
      //string = leerString();
      ArrayList<Puntuacion> puntuaciones;
      if (string == null) {
         puntuaciones = new ArrayList<>();
      } else {
         puntuaciones = gson.fromJson(string, type);
      }
      Vector<String> salida = new Vector<>();
      for (Puntuacion puntuacion : puntuaciones) {
         salida.add(puntuacion.getPuntos()+" "+puntuacion.getNombre());
      }
      return salida;
   }
}

En la variable stringse almacenará la lista de puntuaciones en representación JSON. Para que los datos se almacene de forma no volátil tendrías que implementar los método guardarString() y leerString(). La forma más sencilla sería almacenarlo en un fichero de preferencias. Otra alternativa sería guardarlo en un fichero en la memoria interna o externa. En el próximo capítulo veremos cómo mandar este String a través de Internet.

5.     Modifica el código correspondiente para que se pueda seleccionar esta clase para el almacenamiento.

6.     Ejecuta el proyecto y verifica su funcionamiento. Si visualizas el valor de stringeste ha de ser:

[{"fecha":1478552190154,"nombre":"Mi nombre", "puntos":45000},
 {"fecha":1478552205944,"nombre":"Otro nombre","puntos":31000}]

NOTA: Observa como los atributos son almacenados por orden alfabético.

Práctica: Guardar el string JSON en un fichero.

1.     Implementa los métodos método guardarString(String) y leerString() para que la información de almacene en un fichero de preferencias o en la memoria del dispositivo.

2.    En la versión anterior, la variable string hacia el papel de almacen de la información. En la nueva versión, este papel ha pasado a un fichero o a una preferencia. Elimina la variable global string y conviértela en variable local en los métodos donde sea necesario.

Ejercicio: Guardar una clase en JSON con la librería Gson.

El resultado del ejercicio anterior es muy similar al ejemplo JSON mostrado al principio de este apartado. Sin embargo, no es exactamente igual. En el ejemplo se muestra un objeto JSON que incluye una única propiedad con nombre “puntuaciones”. En el siguiente ejercicio veremos como obtener una estructura como esta.

1.    En AlmacenPuntuacionesGSon añade la siguiente clase:

public class Clase {
  private ArrayList<Puntuacion> puntuaciones = new ArrayList<>();
  private boolean guardado;
}

2.    Reemplaza el código subrayado de los siguientes métodos:

private Type type = new TypeToken<Clase>() {}.getType();

@Override
public void guardarPuntuacion(int puntos, String nombre, long fecha) {
   //string = leerString();
   Clase objeto;
   if (string == null) {
      objeto = new Clase();
   } else {
      objeto = gson.fromJson(string, type);
   }
   objeto.puntuaciones.add(new Puntuacion(puntos, nombre, fecha));
   string = gson.toJson(objeto, type);
   //guardarString(string);
}

@Override
public Vector<String> listaPuntuaciones(int cantidad) {
   //string = leerString();
   Clase objeto;
   if (string == null) {
      objeto = new Clase();
   } else {
      objeto = gson.fromJson(string, type);
   }
   Vector<String> salida = new Vector<>();
   for (Puntuacion puntuacion : objeto.puntuaciones) {
      salida.add(puntuacion.getPuntos()+" "+puntuacion.getNombre());
   }
   return salida;    
}

2.  Ejecuta el proyecto y verifica su funcionamiento. Si visualizas el valor de stringeste ha de ser:

{"guardado":false,
 "puntuaciones":[{"fecha":1478552190154,"nombre":"Mi nombre", "puntos":45000},
                 {"fecha":1478552205944,"nombre":"Otro nombre","puntos":31000}
                ]
}

Los saltos de línea han sido introducidos para facilitar la visualización.