1. 概述

本文将演示如何使用 自定义序列化器 通过 Jackson 2 对 Java 实体进行序列化操作。如果你还想探索 Jackson 2 的更多高级用法,可以参考 Jackson 核心教程

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 上注册自定义序列化器

现在我们来简化 JSON 输出:只序列化 User 的 id 字段,而不是整个 User 对象。目标输出如下:

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

实现步骤很简单粗暴:

  1. ✅ 为 Item 类创建自定义序列化器
  2. ✅ 在 ObjectMapper 中注册该序列化器

自定义序列化器实现:

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

同样会得到通过 @JsonSerialize 指定的自定义 JSON 输出:

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

⚠️ 这种方式特别适合无法直接访问和配置 ObjectMapper 的场景(比如某些框架内部)。

5. 总结

本文展示了通过 Jackson 2 的序列化器实现自定义 JSON 输出的完整流程。关键点总结:

  • ✅ 自定义序列化器需继承 StdSerializer<T>
  • ✅ 可通过 SimpleModule 在 ObjectMapper 全局注册
  • ✅ 也可通过 @JsonSerialize 注解直接绑定到类
  • ❌ 避免在序列化器中执行耗时操作,会影响性能

所有示例代码可在 GitHub 项目 中获取,这是一个基于 Maven 的项目,可直接导入运行。


原始标题:Jackson - Custom Serializer