Tutorial de Api Jackson
Otra característica esencial de la clase ObjectMapper es la capacidad de registrar un serializador y un deserializador personalizados .
Los serializadores y deserializadores personalizados son muy útiles en situaciones en las que la respuesta JSON de entrada o salida tiene una estructura diferente a la clase Java en la que debe serializarse o deserializarse.
Serialización estándar de un gráfico de objetos
Ahora, vamos a serializar una entidad Item con una entidad User:
Clase User.java
package com.ejemplos.jackson;
public class User {
public int id;
public String name;
public User(int id, String name) {
super();
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Clase Item.java
package com.ejemplos.jackson;
public class Item {
public int id;
public String itemName;
public User owner;
public Item(int id, String itemName, User owner) {
super();
this.id = id;
this.itemName = itemName;
this.owner = owner;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public User getOwner() {
return owner;
}
public void setOwner(User owner) {
this.owner = owner;
}
}
Clase EjemploJackson.java
package com.ejemplos.jackson;
import com.fasterxml.jackson.databind.ObjectMapper;
public class EjemploJackson {
public static void main(String[] args) {
ObjectMapper objectMapper = new ObjectMapper();
try {
Item myItem = new Item(1, "theItem", new User(2, "theUser"));
String serialized = objectMapper.writeValueAsString(myItem);
System.out.println(serialized);
}catch (Exception e) {
e.printStackTrace();
}
}
}
Esto dará como resultado una representación JSON completa para ambas entidades:
{
"id": 1,
"itemName": "theItem",
"owner": {
"id": 2,
"name": "theUser"
}
}
Serializador personalizado en ObjectMapper
Ahora, simplifiquemos la salida del JSON anterior serializando solo la identificación del Usuario, no el objeto Usuario completo ; nos gustaría obtener el siguiente JSON más simple:
{
"id": 25,
"itemName": "FEDUfRgS",
"owner": 15
}
En pocas palabras, tendremos que definir un serializador personalizado para los objetos Item:
Clase ItemSerializer.java
package com.ejemplos.jackson;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
public class ItemSerializer extends StdSerializer<Item>{
public ItemSerializer() {
this(null);
}
public ItemSerializer(Class<Item> t) {
super(t);
}
@Override
public void serialize(
Item value, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonProcessingException {
jgen.writeStartObject();
jgen.writeNumberField("id", value.id);
jgen.writeStringField("itemName", value.itemName);
jgen.writeNumberField("owner", value.owner.id);
jgen.writeEndObject();
}
}
Ahora, necesitamos registrar este serializador personalizado con ObjectMapper para la clase Item y realizar la serialización:
Clase EjemploJackson.java
package com.ejemplos.jackson;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
public class EjemploJackson {
public static void main(String[] args) {
ObjectMapper objectMapper = new ObjectMapper();
try {
Item myItem = new Item(1, "theItem", new User(2, "theUser"));
SimpleModule module = new SimpleModule();
module.addSerializer(Item.class, new ItemSerializer());
objectMapper.registerModule(module);
String serialized = objectMapper.writeValueAsString(myItem);
System.out.println(serialized);
}catch (Exception e) {
e.printStackTrace();
}
}
}
Serializador personalizado en la clase
También podemos registrar el serializador directamente en la clase , en lugar de en el ObjectMapper:
Clase Item.java
package com.ejemplos.jackson;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
@JsonSerialize(using = ItemSerializer.class)
public class Item {
public int id;
public String itemName;
public User owner;
public Item(int id, String itemName, User owner) {
super();
this.id = id;
this.itemName = itemName;
this.owner = owner;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public User getOwner() {
return owner;
}
public void setOwner(User owner) {
this.owner = owner;
}
}
Ahora, al realizar la serialización estándar:
Clase EjemploJackson.java
package com.ejemplos.jackson;
import com.fasterxml.jackson.databind.ObjectMapper;
public class EjemploJackson {
public static void main(String[] args) {
ObjectMapper objectMapper = new ObjectMapper();
try {
Item myItem = new Item(1, "theItem", new User(2, "theUser"));
String serialized = objectMapper.writeValueAsString(myItem);
System.out.println(serialized);
}catch (Exception e) {
e.printStackTrace();
}
}
}
Obtendremos la salida JSON personalizada, creada por el serializador, especificada a través de @JsonSerialize:
{
"id": 25,
"itemName": "FEDUfRgS",
"owner": 15
}