Java – Json con Google Gson

Gson convierte objetos de Java en JSON y JSON en objetos, sin anotaciones y sin configuración. Son dos métodos: toJson y fromJson.

La dependencia

<dependency>
  <groupId>com.google.code.gson</groupId>
  <artifactId>gson</artifactId>
  <version>2.14.0</version>
</dependency>

O en Gradle: implementation 'com.google.code.gson:gson:2.14.0'. Es un solo jar de unos 300 KB, sin dependencias propias.

De objeto a JSON

import com.google.gson.*;
import java.util.List;

public class GsonEj {
    record Libro(String titulo, String autor, int anio, List<String> temas) {}

    public static void main(String[] args) {
        Gson gson = new GsonBuilder().setPrettyPrinting().create();

        Libro l = new Libro("El Quijote", "Cervantes", 1605, List.of("novela", "clásico"));
        System.out.println(gson.toJson(l));
    }
}
salida{
  "titulo": "El Quijote",
  "autor": "Cervantes",
  "anio": 1605,
  "temas": [
    "novela",
    "clásico"
  ]
}

Funciona con record, que es la forma natural de declarar un objeto de datos desde Java 16: Gson lo serializa por sus componentes y lo reconstruye por el constructor canónico. Sin setPrettyPrinting() sale todo en una línea, que es lo que quieres para enviarlo por la red.

De JSON a objeto

Libro vuelta = gson.fromJson(json, Libro.class);
System.out.println("de vuelta: " + vuelta.titulo() + " (" + vuelta.anio() + ")");
System.out.println("¿iguales? " + l.equals(vuelta));
salidade vuelta: El Quijote (1605)
¿iguales? true

Una lista: el TypeToken

String lista = """
    [{"titulo":"Uno","autor":"A","anio":2001,"temas":[]},
     {"titulo":"Dos","autor":"B","anio":2002,"temas":[]}]""";

List<Libro> libros = gson.fromJson(lista, new TypeToken<List<Libro>>(){}.getType());
System.out.println("leídos " + libros.size() + ": " + libros.get(1).titulo());
salidaleídos 2: Dos
Ese new TypeToken<…>(){} con las llaves vacías no es un capricho. Java borra los genéricos al compilar, así que List.class no sabe de qué es la lista. El truco consiste en crear una subclase anónima —de ahí las llaves— cuya declaración sí conserva el tipo, y preguntárselo. Sin él, Gson devuelve una lista de LinkedTreeMap y el error aparece más tarde, al usarla.

Los campos que faltan

Libro p = gson.fromJson("{\"titulo\":\"Solo título\"}", Libro.class);
System.out.println("autor=" + p.autor() + " anio=" + p.anio() + " temas=" + p.temas());
salidaautor=null anio=0 temas=null
Gson no se queja. Lo que no viene en el JSON se queda con el valor por omisión del tipo: null en los objetos y 0 en los números. Eso significa que un JSON incompleto no da error, da datos falsos: un precio ausente se convierte en cero. Si el JSON viene de fuera, hay que validar después de convertir, porque Gson no lo va a hacer.

Los nulos, al revés

System.out.println(new Gson().toJson(new Libro("X", null, 0, null)));
System.out.println(new GsonBuilder().serializeNulls().create().toJson(new Libro("X", null, 0, null)));
salida{"titulo":"X","anio":0}
{"titulo":"X","autor":null,"anio":0,"temas":null}

Por omisión, Gson se salta los campos nulos al escribir. Si el otro extremo distingue «no viene» de «viene vacío» —cosa habitual en una API REST con PATCH—, hay que activar serializeNulls().

Sin clase, cuando solo quieres un dato

JsonObject o = JsonParser.parseString(json).getAsJsonObject();
System.out.println(o.get("autor").getAsString());
salidaCervantes

Para leer un campo suelto de una respuesta grande no hace falta declarar la clase entera. JsonObject, JsonArray y getAsString / getAsInt bastan. Ojo con get, que devuelve null si la clave no está: has("clave") antes, o JsonObject.get(...) comprobado.

Para…Usa
Objeto a JSONgson.toJson(objeto)
JSON a objetogson.fromJson(texto, Clase.class)
JSON a listanew TypeToken<List<T>>(){}.getType()
Que se lea biennew GsonBuilder().setPrettyPrinting()
Incluir los nulos.serializeNulls()
Cambiar el nombre de un campola anotación @SerializedName
Un dato sueltoJsonParser.parseString(...)
La alternativa es Jackson, más grande y más configurable, que es la que trae Spring Boot de serie. Para un proyecto pequeño o para una utilidad de línea de órdenes, Gson llega de sobra y pesa mucho menos.

Más información en inglés: JSON with Google Gson.

Todo el código se compiló y se ejecutó con Java 25 LTS en un contenedor limpio antes de publicar esta página; las salidas están copiadas de esa ejecución.

Deja un comentario