Gson (JSON) en Java, con ejemplos
El proyecto de este post los puedes descargar pulsando AQUI.
GSON es un API en Java, desarrollada por Google, que se utiliza para convertir objetos Java a JSON (serialización) y JSON a objetos Java (deserialización). En este tutorial se van a mostrar unos secillos ejemplo de serialización y deserialización con el fin de proporcionar al lector de este artículo unos conocimientos mínimos para que pueda leer y escribir JSON.
Este librería estructura los JSON de la siguiente manera:
- JsonElement: Esta clase representa cualquier elemento del Json que puede ser de alguno de los siguientes 4 tipos:
- JsonObject: Esta clase representa un objeto en el Json; es decir, un conjunto de pares clave-valor donde las claves son strings y los valores son cualquier otro tipo de JsonElement.
- JsonArray: Esta clase representa un array en el Json. Un array es una lista de JsonElements cada uno de los cuales puede ser de un tipo diferente. Se trata de una lista ordenada, por lo que el orden en que se añaden los elementos se conserva.
- JsonPrimitive: Esta clase representa un tipo de dato primitivo u objetos de datos simples (String, Integer, Double, etc.).
- JsonNull: Representa un objeto a null.
JsonObject, JsonArray, JsonPrimitive y JsonNull heredan de la clase JsonElement:
Antes de pasar a mostrar los ejemplos, tenemos que añadir la siguiente dependencia a nuestra aplicación:
Gradle (tal y como esta en el proyecto de Github):
dependencies { compile group: 'com.google.code.gson', name: 'gson', version: '2.8.0' }
Maven:
<dependency> <groupid>com.google.code.gson</groupid> <artifactid>gson</artifactid> <version>2.8.0</version> </dependency>
Para ver los ejemplos de serialización y deserialización, vamos a trabajar con objetos de una clase llamada «FootballPlayer» que representará a un futbolista. La clase FootballPlayer.java es la siguiente:
public class FootballPlayer { private int dorsal; private String name; private List demarcation; private String team; public FootballPlayer(int dorsal, String name, List demarcation, String team) { this.dorsal = dorsal; this.name = name; this.demarcation = demarcation; this.team = team; } // getter y setter @Override public String toString() { return "Dorsal=" + dorsal + ", Name=" + name + ", Demarcation=" + demarcation + ", Team=" + team; } }
Cada futbolista estará representado por su dorsal, nombre, club de futbol en el que juega y una lista de las demarcaciones en las que puede jugar. Un ejemplo de JSON de una lista (de un elemento en este caso) de objetos de la clase «FootballPlayer» sería la siguiente, indicando en la imagen como Gson estructuraría ese JSON:
Por definición todos los elementos del JSON son de tipo JsonElement, por lo que todo el JSON decimos que es un JsonElement. En primer lugar nos encontramos con un JsonArray que es una lista (o array) de objetos. Esto lo podemos reconocer por el símbolo del corchete «[ … ]». Dentro de ese JsonArray no encontramos con un único objeto del tipo JsonObject y ese objeto a su vez contiene una seríe de JsonElements de los cuales 3 son JsonPrimitives y uno vuelve a ser un JsonArray.
Un ejemplo de como pasaríamos este JSON a un objeto de tipo «FootballPlayer» de forma «manual» sería la siguiente (ver ReadJson1.java):
import java.util.ArrayList; import java.util.List; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; /*** * Manual deserialization example * * @author RicardoMoya * */ public class ReadJson1 { public static void main(String[] args) { String json1 = "[{\"dorsal\":6," + "\"name\":\"Iniesta\"," + "\"demarcation\":[\"Right winger\",\"Midfielder\"]," + "\"team\":\"FC Barcelona\"}]"; JsonParser parser = new JsonParser(); // Obtain Array JsonArray gsonArr = parser.parse(json1).getAsJsonArray(); // for each element of array for (JsonElement obj : gsonArr) { // Object of array JsonObject gsonObj = obj.getAsJsonObject(); // Primitives elements of object int dorsal = gsonObj.get("dorsal").getAsInt(); String name = gsonObj.get("name").getAsString(); String team = gsonObj.get("team").getAsString(); // List of primitive elements JsonArray demarcation = gsonObj.get("demarcation").getAsJsonArray(); List listDemarcation = new ArrayList(); for (JsonElement demarc : demarcation) { listDemarcation.add(demarc.getAsString()); } // Object Constructor FootballPlayer iniesta = new FootballPlayer(dorsal, name, listDemarcation, team); System.out.println(iniesta); } } }
Analizando más en detalle el código, lo primero hacemos es definirnos un «parser» (JsonParser) para que pasandole un String en formato Json, este nos lo pase a un objeto de algunas de las clases de Gson; en este caso, a un objeto de la clase JsonArray:
String json1 = "[{\"dorsal\":6," + "\"name\":\"Iniesta\"," + "\"demarcation\":[\"Right winger\",\"Midfielder\"]," + "\"team\":\"FC Barcelona\"}]"; JsonParser parser = new JsonParser(); // Obtain Array JsonArray gsonArr = parser.parse(json1).getAsJsonArray();
Una vez que tenemos un JsonArray, recorremos esta estructura como si de una lista se tratase, siendo cada uno de los elementos de esta lista un objeto de tipo JsonElement. Dentro del «foreach» pasamos cada uno de estos elementos (recordemos que en este caso se trata de un array con un único elemento) a un objeto de la clase JsonObject y a partir de ese objeto obtenemos cada uno de sus atributos con los métodos «getAsXXX()«, dependiendo del tipo de datos que sea. Al final contruimos el objeto FootbalPlayer los los valores del objeto JSON tal y como se indica en el siguiente fragmento de código:
// for each element of array for (JsonElement obj : gsonArr) { // Object of array JsonObject gsonObj = obj.getAsJsonObject(); // Primitives elements of object int dorsal = gsonObj.get("dorsal").getAsInt(); String name = gsonObj.get("name").getAsString(); String team = gsonObj.get("team").getAsString(); // List of primitive elements JsonArray demarcation = gsonObj.get("demarcation").getAsJsonArray(); List listDemarcation = new ArrayList(); for (JsonElement demarc : demarcation) { listDemarcation.add(demarc.getAsString()); } // Object Constructor FootballPlayer iniesta = new FootballPlayer(dorsal, name, listDemarcation, team); System.out.println(iniesta); }
Existe una forma mucho más sencilla de parsear (o deserializar) un JSON sin necesidad de tener que ir mapeando elemento a elemento del objeto. Lo sencillo es que dada una clase y un JSON, este se parsease automáticamente. Un ejemplo de ello es el realizado en «ReadJson2.java» en el que dada una lista de objetos en JSON (que corresponden al equipo titular de la selección Española que gano el mundial del 2010), este te lo transforme a una lista de objetos FootballPlayer de forma automática:
import com.google.gson.Gson; /*** * Automatic deserialization example * * @author RicardoMoya * */ public class ReadJson2 { public static void main(String[] args) { String jsonAll = "[{\"dorsal\":1,\"name\":\"Casillas\",\"demarcation\":[\"Goalkeeper\"],\"team\":\"Real Madrid\"}," + "{\"dorsal\":15,\"name\":\"Ramos\",\"demarcation\":[\"Right back\",\"Centre-back\"],\"team\":\"Real Madrid\"}," + "{\"dorsal\":3,\"name\":\"Pique\",\"demarcation\":[\"Centre-back\"],\"team\":\"FC Barcelona\"}," + "{\"dorsal\":5,\"name\":\"Puyol\",\"demarcation\":[\"Centre-back\"],\"team\":\"FC Barcelona\"}," + "{\"dorsal\":11,\"name\":\"Capdevila\",\"demarcation\":[\"Left back\"],\"team\":\"Villareal\"}," + "{\"dorsal\":14,\"name\":\"Xabi Alonso\",\"demarcation\":[\"Defensive midfield\",\"Midfield\"],\"team\":\"Real Madrid\"}," + "{\"dorsal\":16,\"name\":\"Busquets\",\"demarcation\":[\"Defensive midfield\"],\"team\":\"FC Barcelona\"}," + "{\"dorsal\":8,\"name\":\"Xavi Hernandez\",\"demarcation\":[\"Midfielder\"],\"team\":\"FC Barcelona\"}," + "{\"dorsal\":18,\"name\":\"Pedrito\",\"demarcation\":[\"Left winger\",\"False forward\"],\"team\":\"FC Barcelona\"}," + "{\"dorsal\":6,\"name\":\"Iniesta\",\"demarcation\":[\"Right winger\",\"Midfielder\"],\"team\":\"FC Barcelona\"}," + "{\"dorsal\":7,\"name\":\"Villa\",\"demarcation\":[\"Centre forward\"],\"team\":\"FC Barcelona\"}]"; Gson gson = new Gson(); FootballPlayer[] footballPlayers = gson.fromJson(jsonAll, FootballPlayer[].class); for (FootballPlayer footballPlayer : footballPlayers) { System.out.println(footballPlayer); } } }
Analizando el código detenidamente, nos creamos un objeto «gson» de la clase «Gson» y con el método «fromJson» pasándole como parametros el String con el Json y la clase FootballPlayer, lo transforma automáticamente a una lista de objetos de la clase FootballPlayer, tal y como mostramos en el siguiente fragmento de código:
Gson gson = new Gson(); FootballPlayer[] footballPlayers = gson.fromJson(jsonAll, FootballPlayer[].class);
Por último, vamos a ver el ejemplo contrario de serialización de una serie de objetos de la clase FootballPlayer a un JSON. Para ello nos definimos 11 objetos de la clase FootballPlayer que representan a cada uno de los jugadores del equipo titular de la selección Española que gano el mundial del 2010, y estos lo pasaremos a un JSON, con la estructura de lista de objetos. El ejemplo esta en «WriteJson.java» y su código es el siguiente:
import java.util.Arrays; import java.util.List; import com.google.gson.Gson; /*** * Automatic serialization example * @author RicardoMoya * */ public class WriteJson { public static void main(String[] args) { List spanishTeam = Arrays.asList( new FootballPlayer(1, "Casillas", Arrays.asList("Goalkeeper"), "Real Madrid"), new FootballPlayer(15, "Ramos", Arrays.asList("Right back", "Centre-back"), "Real Madrid"), new FootballPlayer(3, "Pique", Arrays.asList("Centre-back"), "FC Barcelona"), new FootballPlayer(5, "Puyol", Arrays.asList("Centre-back"), "FC Barcelona"), new FootballPlayer(11, "Capdevila", Arrays.asList("Left back"), "Villareal"), new FootballPlayer(14, "Xabi Alonso", Arrays.asList("Defensive midfield", "Midfield"), "Real Madrid"), new FootballPlayer(16, "Busquets", Arrays.asList("Defensive midfield"), "FC Barcelona"), new FootballPlayer(8, "Xavi Hernandez", Arrays.asList("Midfielder"), "FC Barcelona"), new FootballPlayer(18, "Pedrito", Arrays.asList("Left winger", "False forward"), "FC Barcelona"), new FootballPlayer(6, "Iniesta", Arrays.asList("Right winger", "Midfielder"), "FC Barcelona"), new FootballPlayer(7, "Villa", Arrays.asList("Centre forward"), "FC Barcelona") ); String json = new Gson().toJson(spanishTeam); System.out.println(json); } }
En este caso la interpretación es muy sencilla y es que con el método «toJson()» de la clase «GSON» pasándole como parámetro la lista de futbolistas, te devuelve un String en formato JSON con la lista de los futbolistas:
String json = new Gson().toJson(spanishTeam);
En resumen, hemos visto en este tutorial como Gson estructura los JSON y lo relativamente sencillo que es la serialización y deserialización de JSON. Como se ha comentado al principio, el objetivo de este tutorial es mostrar unos sencillos ejemplos del manejo de esta librería para que el lector tenga unos mínimos conocimientos de la misma y pueda empezar a trabajar con este API.
y como se haria el mismo codigo pero sien el objeto un tipo Date ?
Buenas Orlando.
Entiendo que preguntas por si se puede utilizar un tipo Date en JSON.
En JSON estándar no se permiten objetos tipo Date (más información de los tipos permitidos en JSON en https://www.json.org/json-es.html)
Pero lo que sí se puede hacer es convertir un objeto tipo Date time a timestamp (tiempo Unix, que es un número de milisegundos y por tanto un valor permitido) o convertir la fecha al formato String. Esto quiere decir que tanto en origen como en destino tienes que convertir y desconvertir en objeto tipo Date si lo quieres usar como tal.
Hola fenomenos como va ,tengo un problema cuando imprimo el json de sucursales, no me muestra el json completo solo veo su domicilio por que es un objeto pero las listas de objetos me las muestras con dos cochetes y adentro nada apesar de las mismas estar cargadas alguien me puede aclarar por que pasa esto tengo todos los get y set en sus respectivas clases. Muchas gracias saludos
//empezamos a cargar los objetos para serializar el objeto a formaro json
//Productos
Producto producto1=new Producto(1,125,»Bago»,»Tafirol»,true);
Producto producto2=new Producto(2,350,»Ancar»,»Dramamine»,true);
Producto producto3=new Producto(3,4525,»Beta»,»212 vip»,false);
Producto producto4=new Producto(4,1200,»Bago»,»Ibuprofeno»,true);
Producto producto5=new Producto(5,1575,»Ancar»,»Crema Hinds»,false);
Producto producto6=new Producto(6,750,»Beta»,»Kevin»,false);
Producto producto7=new Producto(7,490,»Bago»,»Sertal»,true);
Producto producto8=new Producto(8,95,»Ancar»,»Axe»,false);
Producto producto9=new Producto(9,1350,»Beta»,»Epinefrina»,true);
Producto producto10=new Producto(10,125,»Bago»,»Crema Goycoechea»,false);
//Domicilios
Domicilio domicilio1=new Domicilio(«Tucuman»,2390,»Lanus»,»Buenos Aires»);
Domicilio domicilio2=new Domicilio(«Tucuman»,1894,»Lanus»,»Buenos Aires»);
Domicilio domicilio3=new Domicilio(«Pergamino»,1254,»Lanus»,»Buenos Aires»);
//Obra sociales
ObraSocial obras1=new ObraSocial(1,»Ioma»);
ObraSocial obras2=new ObraSocial(2,»Ioma»);
ObraSocial obras3=new ObraSocial(3,»Accord»);
//Empleados
Empleado empleado1=new Empleado(«Fragas»,»Rodrigo»,36368956,»20-36368956-2″,domicilio1,obras1,»Encargado»);
Empleado empleado2=new Empleado(«Fragapane»,»Luciano»,42368956,»20-42368956-2″,domicilio2,obras2,»Empleado»);
List productosV1= new ArrayList();
productosV1.add(producto1);
productosV1.add(producto10);
//Ventas
Venta venta1=new Venta(«0001»,0,productosV1,4,0,0,empleado2,empleado1,1);
List ventas=new ArrayList();
ventas.add(venta1);
//Clientes
Cliente cliente1=new Cliente(«Serna»,»Mauricio»,34368986,domicilio1,obras3);
List clientes=new ArrayList();
clientes.add(cliente1);
List empleados=new ArrayList();
empleados.add(empleado2);
empleados.add(empleado1);
Sucursal sucursales = new Sucursal(domicilio3, empleados, clientes, ventas);
System.out.println(«\n»);
// Creamos el objeto Gson que se encargara de las conversiones
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String json = gson.toJson(sucursales);
System.out.println(«\n»+json);
Tiene pinta de que las clases contract que define al Cliente tiene algo raro que el Gson no es capaz de reconocer ¿Cómo asignas las variables a la clase Cliente?
ayudaaa! necesito de favor un programa, clase pastel con arreglo de objetos y
excepciones
Tengo este Json
{
«returnState»:1,
«returnData»:{
«16777216»:{
«level»:»1″,
«cate_shop_id»:»16777216″,
«cate_name»:»\u5e97\u94fa\u4ea7\u54c1″
},
«33554432»:{
«level»:»1″,
«cate_shop_id»:»33554432″,
«cate_name»:»\u5316\u5986\u54c1”
},
«50331648»:{
«level»:»1″,
«cate_shop_id»:»50331648″,
«cate_name»:»\u65e5\u7528\u767e\u8d27”,
«child»:{
«50593792»:{
«level»:»2″,
«cate_shop_id»:»50593792″,
«cate_name»:»\u6d17\u6f31\u7528\u54c1”,
«child»:{
«50597888»:{
«level»:»3″,
«cate_shop_id»:»50597888″,
«cate_name»:»\u7259\u818f
},
«50601984»:{
«level»:»3″,
«cate_shop_id»:»50601984″,
«cate_name»:»\u6bdb\u5dfe”
}
}
}
}
}
}
}
Como lo recorro para mostrar esa informacion. como pueden ver hay varios jsonobject uno dentro de otro
Me aparece como que está mal formado, pero de cualquier manera puedes o bien utilizar List si lo que quieres mapear es un listado (elementos entre […] ) o si está está el elemento entre llaves {…} es un objeto que puedes crear.
Por ejemplo para: { «elementoSimple»: 0, «miListado»: [1,2,3], «miObjeto»; {«otroElemento»: 0} }
Podrías hacer:
public class MiClaseInterna {
private int otroElemento;
}
public class MiClase {
private int elementoSimple;
private List <int> miListado;
private MiClaseInterna miObjeto;
}
Hola, muy bueno tu post, felicidades.
He tratado de usar esa forma para parsear un json y no hay forma que pueda, este es el json:
{
«SUCCESS»: [
{
«MESSAGE»: «Server Service List»,
«LIST»: {
«LGTool SE-Tool»: {
«GROUPNAME»: «LGTool SE-Tool»,
«SERVICES»: {
«21»: {
«SERVICEID»: 21,
«SERVICENAME»: «LGTool Remote Services Activation»,
«CREDIT»: «59.0000»,
«ADDITIONAL_NVP»: «a:1:{s:13:\»hide_quantity\»;i:0;}»,
«TIME»: «1-24 Hours»,
«sync_key_data»: «»,
«service_type_price_data»: «»,
«qry_range_credit_info»: [],
«REQUIRED»: «SERIAL_NUMBER»
},
«23»: {
«SERVICEID»: 23,
«SERVICENAME»: «SE-Tool Server (30 LOG)»,
«CREDIT»: «67.0000»,
«ADDITIONAL_NVP»: «a:1:{s:13:\»hide_quantity\»;i:0;}»,
«TIME»: «1-24 Hours»,
«sync_key_data»: «»,
«service_type_price_data»: «»,
«qry_range_credit_info»: [],
«REQUIRED»: «»
}
}
},
«NCK»: {
«GROUPNAME»: «NCK»,
«SERVICES»: {
«19»: {
«SERVICEID»: 19,
«SERVICENAME»: «NCK Dongle / NCK Box 1 Year Activation»,
«CREDIT»: «26.0000»,
«ADDITIONAL_NVP»: «a:1:{s:13:\»hide_quantity\»;i:0;}»,
«TIME»: «1-24 Hours»,
«sync_key_data»: «»,
«service_type_price_data»: «»,
«qry_range_credit_info»: [],
«REQUIRED»: «SERIAL_NUMBER»
}
}
},
«NS PRO»: {
«GROUPNAME»: «NS PRO»,
«SERVICES»: {
«14»: {
«SERVICEID»: 14,
«SERVICENAME»: «NS Pro Activation»,
«CREDIT»: «26.5000»,
«ADDITIONAL_NVP»: «a:1:{s:13:\»hide_quantity\»;i:0;}»,
«TIME»: «1-24 Hours»,
«sync_key_data»: «»,
«service_type_price_data»: «»,
«qry_range_credit_info»: [],
«REQUIRED»: «»
}
}
}
}
}
],
«more_info»: «Server Service List»
}