You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Jackson的StdSerializer层为POJO转JSON结果添加customFields对象?

基于Jackson StdSerializer扩展已有JSON输出添加自定义字段

问题场景

现有POJO:

public class Person {
  public long id;
  public String someOtherId;
  public String vollName;
  public int alter;
}

通过Mixin实现字段映射与过滤,生成JSON:

@JsonIncludeProperties( { "id", "name", "age", "customFields" } )
abstract class PersonM extends Person {
  @JsonProperty( "id" ) String someOtherId;
  @JsonProperty( "name" ) String vollName;
  @JsonProperty( "age" ) String alter;
}

// 序列化代码
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn( Person.class, PersonM.class );
String body = mapper.writeValueAsString( person );

当前输出JSON:

{
  "id": "xxxxxx",
  "name": "Aaaa Bbbb",
  "age": 111
}

需要扩展输出,添加customFields节点,内容基于POJO的id字段,且不允许修改原POJO:

{
  "id": "xxxxxx",
  "name": "Aaaa Bbbb",
  "age": 111,
  "customFields": {
    "originalId": 333333
  }
}

解决方案:自定义StdSerializer复用默认序列化逻辑

我们可以通过自定义StdSerializer,先利用Jackson已有的序列化规则(包括Mixin配置)生成基础JSON节点,再添加自定义字段,避免重复实现所有字段的序列化。

1. 实现自定义序列化器

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectNode;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;

import java.io.IOException;

public class PersonSerializer extends StdSerializer<Person> {

    public PersonSerializer() {
        super(Person.class);
    }

    @Override
    public void serialize(Person person, JsonGenerator gen, SerializerProvider provider) throws IOException {
        // 获取已配置好的ObjectMapper(包含Mixin规则),将Person转换为基础ObjectNode
        ObjectMapper mapper = provider.getConfig().getObjectMapper();
        ObjectNode objectNode = mapper.valueToTree(person);
        
        // 构建customFields节点并填充数据
        ObjectNode customFields = mapper.createObjectNode();
        customFields.put("originalId", person.id);
        
        // 将customFields添加到基础节点中
        objectNode.set("customFields", customFields);
        
        // 将最终的JSON结构写入输出流
        gen.writeTree(objectNode);
    }
}

2. 注册序列化器并执行序列化

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;

public class Main {
    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        // 先注册Mixin配置,保证基础字段的映射规则生效
        mapper.addMixIn(Person.class, PersonM.class);
        
        // 注册自定义序列化器
        mapper.registerModule(new SimpleModule()
                .addSerializer(Person.class, new PersonSerializer()));
        
        // 构造测试对象
        Person person = new Person();
        person.id = 333333;
        person.someOtherId = "xxxxxx";
        person.vollName = "Aaaa Bbbb";
        person.alter = 111;
        
        // 序列化并输出
        String body = mapper.writeValueAsString(person);
        System.out.println(body);
    }
}

方案说明

  • 复用已有逻辑:通过mapper.valueToTree(person)直接利用已注册的Mixin规则生成基础JSON节点,无需重新定义所有字段的序列化规则
  • 增量扩展:仅在基础节点上添加customFields字段,避免重复造轮子
  • 无侵入:完全在序列化层实现,不需要修改原POJO的代码

内容的提问来源于stack exchange,提问作者injecteer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 20:05:28