W3docs

Java JSON con Gson

Analiza y serializa JSON en Java con la biblioteca Gson de Google: toJson, fromJson y TypeToken.

JSON es la lengua franca de las APIs web modernas, y las aplicaciones Java constantemente necesitan convertir objetos en JSON y volver a parsear JSON en objetos. Gson es la biblioteca de código abierto de Google para exactamente esto: un kit de herramientas pequeño y sin dependencias que mapea objetos Java a texto JSON y viceversa con casi ningún código repetitivo. Este capítulo muestra cómo funciona Gson y los patrones que usarás a diario.

Si eres nuevo en el formato en sí, comienza con la introducción a JSON; para la biblioteca alternativa principal, consulta Java JSON con Jackson.

Agregar Gson a tu Proyecto

Gson no forma parte del JDK, por lo que debes añadirlo como dependencia. Con Maven lo declaras en tu pom.xml:

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

Con Gradle la misma dependencia es una sola línea:

implementation 'com.google.code.gson:gson:2.11.0'

Todo lo que haces con Gson pasa por una única clase de punto de entrada, Gson. Normalmente creas una instancia y la reutilizas — es thread-safe y económica de compartir.

import com.google.gson.Gson;

Gson gson = new Gson();

Serializar Objetos a JSON

Convertir un objeto Java en texto JSON se llama serialización, y Gson lo hace con toJson(). Le pasas cualquier objeto y Gson recorre sus campos usando reflexión, produciendo un string JSON. No se requieren anotaciones ni configuración para clases ordinarias.

class Book {
    String title;
    String author;
    int year;
    boolean inStock;

    Book(String title, String author, int year, boolean inStock) {
        this.title = title;
        this.author = author;
        this.year = year;
        this.inStock = inStock;
    }
}

Gson gson = new Gson();
Book b = new Book("Clean Code", "Robert Martin", 2008, true);
String json = gson.toJson(b);
// {"title":"Clean Code","author":"Robert Martin","year":2008,"inStock":true}

Los nombres de los campos se convierten en claves JSON, y los tipos Java se mapean a los tipos JSON naturales: String a un string entre comillas, int/double a un número, boolean a true/false. Un campo null se omite por defecto.

Deserializar JSON a Objetos

La dirección inversa — deserialización — usa fromJson(). Pasas el texto JSON y la Class destino, y Gson crea una instancia y rellena los campos haciendo coincidir las claves JSON con los nombres de los campos.

String json = "{\"title\":\"Clean Code\",\"author\":\"Robert Martin\",\"year\":2008,\"inStock\":true}";

Gson gson = new Gson();
Book b = gson.fromJson(json, Book.class);

System.out.println(b.title);  // Clean Code
System.out.println(b.year);   // 2008

Si una clave JSON no tiene campo coincidente, Gson la ignora; si un campo no tiene clave coincidente, se queda en su valor por defecto (null, 0 o false). Este comportamiento indulgente hace que Gson sea resistente cuando una API añade nuevos campos.

TypeToken para Colecciones Genéricas

Debido al borrado de tipos, Java descarta la información de tipo genérico en tiempo de ejecución, por lo que gson.fromJson(json, List.class) no puede saber que quieres una List<Book> — devolvería una List de objetos LinkedTreeMap. Gson resuelve esto con TypeToken, que captura el tipo genérico completo para que la deserialización produzca los elementos que esperas.

import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.List;

String json = "[{\"title\":\"Effective Java\",\"year\":2018}]";

Type listType = new TypeToken<List<Book>>(){}.getType();
List<Book> books = gson.fromJson(json, listType);

Usa un TypeToken siempre que el tipo destino involucre genéricos — List<T>, Map<K, V>, o combinaciones anidadas. Para clases simples sin genéricos, la forma simple Book.class es suficiente.

Pretty Printing y Configuración Personalizada

El Gson por defecto produce JSON compacto en una sola línea. Para configurar el comportamiento, construyes una instancia con GsonBuilder. La solicitud más común es el pretty printing — salida indentada y legible por humanos para registros y archivos de configuración.

import com.google.gson.GsonBuilder;

Gson gson = new GsonBuilder()
        .setPrettyPrinting()
        .serializeNulls()        // include null fields instead of dropping them
        .create();

System.out.println(gson.toJson(b));

GsonBuilder controla muchos otros comportamientos. Algunos que encontrarás con frecuencia:

Método del builderEfecto
setPrettyPrinting()Salida indentada en múltiples líneas
serializeNulls()Emite campos null en lugar de omitirlos
setDateFormat(...)Controla cómo se formatean los valores Date
registerTypeAdapter(...)Conecta un serializador/deserializador personalizado para un tipo
excludeFieldsWithoutExposeAnnotation()Solo serializa campos marcados con @Expose

Para control total sobre un tipo, registras un adaptador personalizado que implementa JsonSerializer y/o JsonDeserializer — útil cuando un campo necesita un formato especial que la reflexión no puede inferir.

Un Ejemplo Práctico: Serializar, Parsear y Round-Trip

Gson en sí no está en el classpath de este ejecutor, por lo que el programa a continuación demuestra los mismos conceptos usando solo el JDK: serializa un record a JSON manualmente, parsea el texto de vuelta en campos, reconstruye el objeto y confirma que el round-trip no tiene pérdidas. Esto es exactamente lo que gson.toJson() y gson.fromJson() automatizan por ti.

java— editable, runs on the server

Qué extraer de la ejecución:

  • La primera línea muestra la serialización: el record Book se convierte en {"title":"Clean Code","author":"Robert Martin","year":2008,"inStock":true}, donde cada campo es una clave JSON y los tipos se mapean a sus formas JSON naturales — exactamente lo que produce gson.toJson().
  • La segunda línea muestra la deserialización: parsear ese texto de vuelta y reconstruir un Book, el mismo trabajo que hace gson.fromJson(json, Book.class) en una sola llamada.
  • Round-trip equal? true demuestra que la conversión no tiene pérdidas — serializar y luego deserializar produce un objeto igual al original, la propiedad que busca todo mapeador JSON.
  • La línea Array JSON muestra una List<Book> renderizada como un array JSON de objetos, la estructura que deserializarías con un TypeToken<List<Book>>.
  • El bloque Pretty muestra salida indentada en múltiples líneas, ilustrando lo que te da GsonBuilder.setPrettyPrinting() comparado con el valor compacto por defecto.

Práctica

Práctica
En Gson, ¿por qué necesitas un TypeToken para deserializar un List<Book> en lugar de simplemente pasar List.class?
En Gson, ¿por qué necesitas un TypeToken para deserializar un List<Book> en lugar de simplemente pasar List.class?
Was this page helpful?