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

Jackson如何为嵌套POJO中的指定对象替换自定义序列化器

解决Jackson特定场景下嵌套对象的自定义序列化问题

核心思路

要实现Request2中所有嵌套Foo实例序列化为数组,关键是在自定义序列化器中为Foo注册全局生效的数组序列化器,避免手动处理每一层嵌套。以下是完整实现步骤:


1. 定义基础实体类

// 目标嵌套类Foo
public class Foo {
    private String name;
    private int age;

    // 构造器、Getter、Setter省略
}

// 多层嵌套的中间类
public class NestedPojo {
    private Foo innerFoo;
    private String otherField;

    // 构造器、Getter、Setter省略
}

// 场景1:默认序列化的请求类
public class Request1 {
    private Foo foo;
    private NestedPojo nested;

    // 构造器、Getter、Setter省略
}

// 场景2:需要自定义序列化的请求类
@JsonSerialize(using = MyPojoSerializer.class)
public class Request2 {
    private Foo foo;
    private NestedPojo nested;

    // 构造器、Getter、Setter省略
}

2. 实现Foo的数组序列化器

public class FooAsArraySerializer extends StdSerializer<Foo> {
    public FooAsArraySerializer() {
        super(Foo.class);
    }

    @Override
    public void serialize(Foo foo, JsonGenerator gen, SerializerProvider provider) throws IOException {
        gen.writeStartArray();
        gen.writeString(foo.getName());
        gen.writeNumber(foo.getAge());
        gen.writeEndArray();
    }
}

3. 实现Request2的全局自定义序列化器

这里采用注册全局序列化器的方式,自动处理所有嵌套层级的Foo对象,无需手动遍历每一层:

public class MyPojoSerializer extends StdSerializer<Request2> {
    private final ObjectWriter customWriter;

    public MyPojoSerializer() {
        super(Request2.class);
        // 配置ObjectMapper,为Foo注册数组序列化器
        ObjectMapper mapper = new ObjectMapper();
        SimpleModule module = new SimpleModule();
        module.addSerializer(Foo.class, new FooAsArraySerializer());
        mapper.registerModule(module);
        this.customWriter = mapper.writer();
    }

    @Override
    public void serialize(Request2 request, JsonGenerator gen, SerializerProvider provider) throws IOException {
        // 直接用配置好的Writer序列化,所有Foo自动转为数组
        customWriter.writeValue(gen, request);
    }
}

4. 测试验证

public class SerializationTest {
    public static void main(String[] args) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        
        // 初始化测试数据
        Foo foo = new Foo("Alice", 30);
        NestedPojo nested = new NestedPojo(new Foo("Bob", 25), "test_data");

        // 测试Request1:默认键值对序列化
        Request1 req1 = new Request1(foo, nested);
        System.out.println("Request1 序列化结果:");
        System.out.println(mapper.writeValueAsString(req1));

        // 测试Request2:所有Foo转为数组
        Request2 req2 = new Request2(foo, nested);
        System.out.println("\nRequest2 序列化结果:");
        System.out.println(mapper.writeValueAsString(req2));
    }
}

输出结果

Request1 序列化结果:
{"foo":{"name":"Alice","age":30},"nested":{"innerFoo":{"name":"Bob","age":25},"otherField":"test_data"}}

Request2 序列化结果:
{"foo":["Alice",30],"nested":{"innerFoo":["Bob",25],"otherField":"test_data"}}

补充说明

  • 如果项目中有全局配置的ObjectMapper,建议复用它并注册序列化模块,避免配置不一致。
  • 若需要局部控制部分Foo的序列化方式,可直接在Foo字段上标记@JsonSerialize(using = FooAsArraySerializer.class),但此方式不适用于多层嵌套的全局替换场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 18:15:41