Java JSON con Jackson
Analiza, genera y vincula JSON en Java con la biblioteca Jackson — ObjectMapper y enlace de datos.
Jackson es la biblioteca JSON estándar de facto para Java. El JDK no incluye ninguna API JSON propia, por lo que casi todas las aplicaciones Spring, Quarkus o Micronaut recurren a Jackson para convertir objetos Java en texto JSON y viceversa. Su punto de entrada es una única clase de trabajo — ObjectMapper — que se encarga de las dos tareas que siempre se necesitan: serialización (objeto Java → JSON) y deserialización (JSON → objeto Java).
Si eres nuevo en JSON en Java, comienza con la introducción a JSON; para una biblioteca alternativa más ligera, consulta el capítulo de Gson. Esta página cubre cómo añadir Jackson, los tres niveles de su API, el enlace de datos, el modelo de árbol y las anotaciones que controlan el mapeo.
Agregar Jackson a tu proyecto
Jackson no forma parte del JDK, por lo que debes declararlo como dependencia. El artefacto jackson-databind incluye de forma transitiva los otros dos módulos principales (jackson-core y jackson-annotations).
<!-- Maven -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.1</version>
</dependency>// Gradle
implementation 'com.fasterxml.jackson.core:jackson-databind:2.17.1'Las tres formas de trabajar con JSON
Jackson expone los mismos datos de tres maneras distintas. Elige el nivel que se ajuste a la tarea:
| Enfoque | Tipo principal | Úsalo cuando |
|---|---|---|
| Enlace de datos | ObjectMapper.readValue / writeValue | Tienes un POJO o record que refleja el JSON — el caso más común |
| Modelo de árbol | JsonNode vía readTree | La forma es dinámica o solo necesitas unos pocos campos |
| Streaming | JsonParser / JsonGenerator | Documentos muy grandes donde no puedes mantener todo el árbol en memoria |
El enlace de datos es lo que se usa el 90% del tiempo; los otros dos son escotillas de escape.
Enlace de datos: objetos a JSON y viceversa
ObjectMapper.writeValueAsString serializa cualquier objeto Java leyendo sus getters (o los componentes del record); readValue hace lo contrario, haciendo coincidir los nombres de campos JSON con tus campos. Un record es el destino más limpio — Jackson 2.12+ se enlaza a su constructor canónico automáticamente, por lo que no necesitas escribir getters ni un constructor sin argumentos.
import com.fasterxml.jackson.databind.ObjectMapper;
record User(String name, int age, boolean active) {}
ObjectMapper mapper = new ObjectMapper();
// serialize: Java -> JSON
User ada = new User("Ada", 36, true);
String json = mapper.writeValueAsString(ada);
// {"name":"Ada","age":36,"active":true}
// deserialize: JSON -> Java
User back = mapper.readValue(json, User.class);
System.out.println(back.name()); // AdaPara colecciones y genéricos, pasa a Jackson un TypeReference para que el tipo de elemento sobreviva al borrado de tipos:
import com.fasterxml.jackson.core.type.TypeReference;
List<User> users = mapper.readValue(jsonArray, new TypeReference<List<User>>() {});El modelo de árbol: cuando la forma es desconocida
Cuando no tienes (o no quieres) una clase correspondiente, analiza el JSON en un árbol genérico JsonNode y navega por él con claves. Esto imita lo que hace un analizador manual de Map/List, pero con accesores con reconocimiento de tipos como asInt() y asText().
import com.fasterxml.jackson.databind.JsonNode;
JsonNode root = mapper.readTree(json);
String name = root.get("name").asText();
int age = root.get("age").asInt();
JsonNode first = root.get("languages").get(0); // array access by indexControlar el mapeo con anotaciones
Los nombres de campos JSON raramente coinciden perfectamente con las convenciones de Java. Un puñado de anotaciones cierra la brecha sin cambiar los nombres de tus campos:
| Anotación | Efecto |
|---|---|
@JsonProperty("user_name") | Mapea un campo a una clave JSON diferente |
@JsonIgnore | Omite un campo en ambas direcciones |
@JsonInclude(NON_NULL) | Elimina los campos null de la salida |
@JsonCreator / @JsonFormat | Construcción personalizada / formato de fecha |
record Account(
@JsonProperty("user_name") String userName,
@JsonIgnore String passwordHash) {}Un ejemplo completo: serializar, analizar y enlazar manualmente
Jackson no está en el classpath de este ejecutor, por lo que el programa a continuación construye los mismos conceptos — un escritor JSON, un analizador de descenso recursivo en un árbol Map/List, y el enlace en un record — usando solo java.util. Es exactamente lo que ObjectMapper hace internamente: recorrer un gráfico de objetos para emitir texto, y tokenizar texto para reconstruir un árbol.
Lo que hay que aprender de la ejecución:
- La serialización recorre un gráfico de objetos y emite texto. La línea
serializedmuestra unMap/Listanidado renderizado como{"name":"Ada",...,"languages":["Java","Ada"]}— un array dentro de un objeto.ObjectMapper.writeValueAsStringhace el mismo recorrido recursivo sobre los getters de tu POJO o los componentes de un record. - El análisis reconstruye primero un árbol genérico. El tipo en tiempo de ejecución del valor analizado es
LinkedHashMap, noUser— exactamente el modelo de árbol de Jackson, dondereadTreete da unJsonNodeque navegas por clave antes de que intervenga ninguna clase. - Los números JSON se convierten en números Java, con una decisión de tipo. El campo
agevolvió como unInteger(42) porque el texto no tenía punto decimal; el analizador eligióIntegersobreDouble. Jackson toma la decisión idéntica, razón por la cual un campointse enlaza limpiamente mientras que3.14llegaría como unDouble. - El acceso a los campos es por nombre y el orden se preserva. Usar
LinkedHashMapmantuvo las claves en orden de inserción, por lo quenamese lee antes queage. Jackson preserva el orden de las claves del objeto de la misma manera, razón por la cual el JSON procesado en un viaje de ida y vuelta se ve igual que el original. - El viaje de ida y vuelta es sin pérdida cuando el modelo coincide. La última línea re-serializó el árbol analizado al mismo JSON del que vino, y el
Userrecord tipado enlazóname,ageylanguagescorrectamente — el punto central del enlace de datos: texto dentro, objeto fuera, texto de vuelta, sin deriva.