Tutorial de Api Jackson
Jackson Annotations son un conjunto de anotaciones Java que se utilizan para personalizar la serialización y deserialización de objetos Java a JSON (y viceversa) en la biblioteca Jackson.
A continuación se presentan todas las Jackson Annotations comunes:
@JsonAnyGetter
@JsonAnyGetter
indica que el método debe ser utilizado para serializar cualquier propiedad que no esté mapeada a una propiedad de la clase. Por ejemplo:
package com.ejemplos.jackson;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
public class Person {
private String name;
private Map<String, String> additionalProperties = new HashMap<>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@JsonAnyGetter
public Map<String, String> getAdditionalProperties() {
return additionalProperties;
}
}
@JsonAnySetter
@JsonAnySetter
indica que el método debe ser utilizado para deserializar cualquier propiedad que no esté mapeada a una propiedad de la clase. Por ejemplo:
package com.ejemplos.jackson;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnySetter;
public class Person {
private String name;
private Map<String, String> additionalProperties = new HashMap<>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@JsonAnySetter
public void setAdditionalProperties(String key, String value) {
additionalProperties.put(key, value);
}
}
@JsonAutoDetect
@JsonAutoDetect
indica la visibilidad de los campos que se serializan y deserializan.
La clase JsonAutoDetect.Visibility contiene constantes que coinciden con los niveles de visibilidad en Java, lo que significa ANY, DEFAULT, NON_PRIVATE, NONE, PROTECTED_AND_PRIVATE y PUBLIC_ONLY. Por ejemplo:
package com.ejemplos.jackson;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY )
public class PersonAutoDetect {
private long personId = 123;
public String name = null;
}
@JsonCreator
@JsonCreator
indica que un método debe ser utilizado para crear una instancia de la clase durante la deserialización.
La anotación @JsonCreator es útil en situaciones en las que no se puede utilizar la anotación @JsonSetter. Por ejemplo, los objetos inmutables no tienen métodos de configuración, por lo que necesitan que se inyecten sus valores iniciales en el constructor.
Para indicarle a Jackson que debe llamar al constructor de PersonImmutable, debemos agregar la anotación @JsonCreator al constructor. Pero eso no es suficiente por sí solo. También debemos anotar los parámetros del constructor para indicarle a Jackson qué campos del objeto JSON deben pasar a qué parámetros del constructor. Así es como se ve la clase PersonImmutable con las anotaciones @JsonCreator y @JsonProperty agregadas:
package com.ejemplos.jackson;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
public class PersonImmutable {
private long id = 0;
private String name = null;
@JsonCreator
public PersonImmutable( @JsonProperty("id") long id, @JsonProperty("name") String name ) {
this.id = id;
this.name = name;
}
public long getId() {
return id;
}
public String getName() {
return name;
}
}
@JsonIgnore
@JsonIgnore
indica que una propiedad debe ser ignorada durante la serialización y deserialización. Por ejemplo:
package com.ejemplos.jackson;
import com.fasterxml.jackson.annotation.JsonIgnore;
public class PersonIgnore {
private String name;
@JsonIgnore
private String password;
}
@JsonIgnoreProperties
@JsonIgnoreProperties
indica que ciertas propiedades deben ser ignoradas durante la serialización y deserialización. Por ejemplo:
package com.ejemplos.jackson;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties({"password", "email"})
public class Person {
private String name;
private String password;
private String email;
}
@JsonIgnoreType
La anotación @JsonIgnoreType
indica que una clase o interfaz y sus campos deben ser ignorados durante la serialización y deserialización. Esta anotación se aplica a una clase o interfaz y no a campos individuales. Aquí hay un ejemplo:
package com.ejemplos.jackson;
public class Person {
private String name;
private int age;
private SecretData secretData;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public SecretData getSecretData() {
return secretData;
}
public void setSecretData(SecretData secretData) {
this.secretData = secretData;
}
}
package com.ejemplos.jackson;
import com.fasterxml.jackson.annotation.JsonIgnoreType;
@JsonIgnoreType
public class SecretData {
private String secretKey;
private String secretValue;
public String getSecretKey() {
return secretKey;
}
public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}
public String getSecretValue() {
return secretValue;
}
public void setSecretValue(String secretValue) {
this.secretValue = secretValue;
}
}
@JsonInclude
La anotación @JsonInclude
de Jackson se utiliza para especificar cuándo se deben incluir las propiedades de una clase al serializar un objeto en formato JSON. Se puede colocar en una clase o en una propiedad individual y acepta varios valores para configurar su comportamiento.
Por ejemplo, si queremos que una propiedad se incluya solo si su valor no es nulo, podemos usar la anotación de la siguiente manera:
package com.ejemplos.jackson;
import com.fasterxml.jackson.annotation.JsonInclude;
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Person {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
@JsonProperty
La anotación @JsonProperty
se utiliza para personalizar el nombre de una propiedad durante la serialización y deserialización de objetos JSON. Por defecto, Jackson utiliza los nombres de las propiedades Java para las propiedades JSON correspondientes, pero esto se puede cambiar utilizando @JsonProperty
.
Por ejemplo, si tenemos una clase Person con una propiedad "firstName", pero queremos que la propiedad JSON se llame "first_name", podemos usar @JsonProperty
de la siguiente manera:
package com.ejemplos.jackson;
import com.fasterxml.jackson.annotation.JsonProperty;
public class Contact {
@JsonProperty(value = "phone_number")
private String phoneNumber;
@JsonProperty(value = "street_name", required = true)
private String street;
@JsonProperty(value = "zip_code", required = true)
private String zip;
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getZip() {
return zip;
}
public void setZip(String zip) {
this.zip = zip;
}
}
@JsonRawValue
La anotación @JsonRawValue
se utiliza para indicar que un campo debe ser serializado y deserializado como un valor JSON sin ser citado ni escapado. Esto significa que el valor se incluirá directamente en la representación JSON, sin ser procesado por el serializador o deserializador de Jackson.
Por ejemplo, si tenemos una clase Product con un campo "description" que contiene un valor JSON sin formato, podemos utilizar @JsonRawValue
de la siguiente manera:
package com.ejemplos.jackson;
import com.fasterxml.jackson.annotation.JsonRawValue;
public class User {
private String name;
@JsonRawValue
private String profile;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getProfile() {
return profile;
}
public void setProfile(String profile) {
this.profile = profile;
}
@Override
public String toString() {
return "User [name=" + name + ", profile=" + profile + "]";
}
}
package com.ejemplos.jackson;
import com.fasterxml.jackson.databind.ObjectMapper;
public class EjemploJackson {
public static void main(String[] args) {
try {
// Crear un objeto User
User user = new User();
user.setName("John Smith");
user.setProfile("{\"age\": 35, \"occupation\": \"developer\"}");
// Serializar el objeto a una cadena JSON
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(user);
System.out.println(json);
}catch (Exception e) {
e.printStackTrace();
}
}
}
{"name":"John Smith","profile":{"age": 35, "occupation": "developer"}}
@JsonFormat
La anotación @JsonFormat
se utiliza en Jackson para especificar el formato de serialización y deserialización de un campo de una clase de modelo. Se puede utilizar para dar formato a campos que representan fechas, horas, números y otras entidades.
La anotación @JsonFormat
admite varios parámetros, incluyendo:
- pattern: Especifica un patrón de formato para el campo. Por ejemplo, "yyyy-MM-dd" para representar fechas en formato "año-mes-día".
- shape: Define la forma de la representación del valor. Por ejemplo, "STRING" para representar el valor como una cadena o "NUMBER_INT" para representar el valor como un número entero.
- locale: Define la configuración regional para la interpretación de valores de fecha y hora.
- timezone: Define la zona horaria para la interpretación de valores de fecha y hora.
Aquí hay algunos ejemplos de cómo se puede utilizar la anotación @JsonFormat
para dar formato a campos de una clase de modelo:
package com.ejemplos.jackson;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
public class Event {
private String name;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
private Date eventTime;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getEventTime() {
return eventTime;
}
public void setEventTime(Date eventTime) {
this.eventTime = eventTime;
}
}
package com.ejemplos.jackson;
import java.util.Date;
import com.fasterxml.jackson.databind.ObjectMapper;
public class EjemploJackson {
public static void main(String[] args) {
ObjectMapper objectMapper = new ObjectMapper();
try {
Event event = new Event();
event.setName("Concert");
event.setEventTime(new Date());
String json = objectMapper.writeValueAsString(event);
System.out.println(json);
}catch (Exception e) {
e.printStackTrace();
}
}
}
{
"name": "Concert",
"eventTime": "2023-04-15T20:00:00.000-05:00"
}
package com.ejemplos.jackson;
import com.fasterxml.jackson.annotation.JsonFormat;
public class User {
private String name;
@JsonFormat(shape = JsonFormat.Shape.NUMBER_INT)
private boolean active;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
}
package com.ejemplos.jackson;
import com.fasterxml.jackson.databind.ObjectMapper;
public class EjemploJackson {
public static void main(String[] args) {
ObjectMapper objectMapper = new ObjectMapper();
try {
User user = new User();
user.setName("John");
user.setActive(true);
String json = objectMapper.writeValueAsString(user);
System.out.println(json);
}catch (Exception e) {
e.printStackTrace();
}
}
}
{"name":"John","active":1}