Contents

Jackson自定义序列化器

1. 概述

这个快速教程将展示如何使用 Jackson 2 使用Custom Serializer 序列化 Java 实体。

2. 对象图的标准序列化

让我们定义 2 个简单的实体,看看 Jackson 如何在没有任何自定义逻辑的情况下序列化它们:

public class User {
    public int id;
    public String name;
}
public class Item {
    public int id;
    public String itemName;
    public User owner;
}

现在,让我们用User实体序列化一个Item实体:

Item myItem = new Item(1, "theItem", new User(2, "theUser"));
String serialized = new ObjectMapper().writeValueAsString(myItem);

这将为两个实体生成完整的 JSON 表示:

{
    "id": 1,
    "itemName": "theItem",
    "owner": {
        "id": 2,
        "name": "theUser"
    }
}

3. ObjectMapper上的自定义序列化器

现在,让我们通过仅序列化Userid而不是整个User对象**来简化上面的 JSON 输出;**我们希望得到以下更简单的 JSON:

{
    "id": 25,
    "itemName": "FEDUfRgS",
    "owner": 15
}

简单地说,我们必须为Item对象定义一个自定义的序列化器:

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();
    }
}

现在,我们需要将这个自定义序列化器注册到Item类的**ObjectMapper中,并执行序列化:

Item myItem = new Item(1, "theItem", new User(2, "theUser"));
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(Item.class, new ItemSerializer());
mapper.registerModule(module);
String serialized = mapper.writeValueAsString(myItem);

就是这样——我们现在有了Item->User实体的更简单的自定义 JSON 序列化。

4. 类上的自定义序列化器

我们也可以直接在类上注册序列化器,而不是在ObjectMapper上:

@JsonSerialize(using = ItemSerializer.class)
public class Item {
    ...
}

现在,在执行标准序列化时:

Item myItem = new Item(1, "theItem", new User(2, "theUser"));
String serialized = new ObjectMapper().writeValueAsString(myItem);

我们将获得由序列化程序创建的自定义 JSON 输出,通过*@JsonSerialize*指定:

{
    "id": 25,
    "itemName": "FEDUfRgS",
    "owner": 15
}

这在无法直接访问和配置ObjectMapper时很有帮助。