0

0

Jackson 自定义序列化器中正确嵌套序列化子类字段的完整教程

心靈之曲

心靈之曲

发布时间:2026-01-22 10:57:25

|

404人浏览过

|

来源于php中文网

原创

Jackson 自定义序列化器中正确嵌套序列化子类字段的完整教程

本文详解如何在 jackson 自定义 `jsonserializer` 中正确序列化多态集合中的子类实例(如 `dog`),避免字段丢失问题,通过 `writeobjectfield` 实现自动委托序列化,并补充反序列化注意事项。

在使用 Jackson(尤其是 XmlMapper)处理多态对象(如 List)时,若为容器类(如 Zoo)编写自定义序列化器,直接调用 writeNullField() 或手动写入字段名会导致子类实际数据丢失——因为这仅生成空标签(如 ),并未触发 Jackson 对 Dog 实例本身的序列化逻辑。

根本原因在于:jg.writeNullField("Dog") 仅向输出流写入一个名为 "Dog" 的 null 值字段,完全绕过了 Jackson 的类型发现、注解解析与字段遍历机制;而单独序列化 dog 时,Jackson 默认使用标准 Bean 序列化器,自动读取 @JsonProperty、可见性规则及字段值,因此能正常输出

✅ 正确做法是:在自定义序列化器中,将子对象交还给 Jackson 的默认序列化流程。使用 JsonGenerator.writeObjectField(String fieldName, Object value) 方法——它会自动根据 value 的实际类型(如 Dog),查找并委托其对应的序列化器(可能是默认 BeanSerializer 或其他自定义器),从而完整输出所有可序列化字段。

以下是修复后的 ZooSerializer 完整实现:

西语写作助手
西语写作助手

西语助手旗下的AI智能写作平台,支持西语语法纠错润色、论文批改写作

下载
public class ZooSerializer extends StdSerializer {
    public ZooSerializer() {
        this(null);
    }

    public ZooSerializer(Class t) {
        super(t);
    }

    @Override
    public void serialize(Zoo zoo, JsonGenerator jg, SerializerProvider sp) 
            throws IOException {
        jg.writeStartObject();
        for (Animal animal : zoo.animals) {
            String typeName = animal.getClass().getSimpleName();
            // ✅ 关键:委托 Jackson 自动序列化 animal 实例
            jg.writeObjectField(typeName, animal);
        }
        jg.writeEndObject();
    }
}

配合示例测试代码运行后,输出即变为符合预期的嵌套 XML:


  
    Collie
    6
  

⚠️ 重要注意事项:

  • 反序列化需配套自定义 JsonDeserializer:当前序列化输出无类型标识(如 @class 字段或 XML 属性),Jackson 无法自动推断 标签应反序列化为 Dog 实例。若需反序列化,必须实现 ZooDeserializer,解析元素名(如 "Dog")并手动构造对应子类对象。
  • 字段可见性需保持一致:确保 Dog.breed/Dog.age 满足 Jackson 默认可见性规则(如 public 字段,或配置 MapperFeature.INFER_PROPERTY_MUTATORS = true)。
  • 避免重复注解冲突:若已在 Animal 或子类上使用 @JsonTypeInfo,则无需手动按类名写字段,应优先采用 Jackson 内置多态支持,而非自定义序列化器。

总结:自定义序列化器不是“从零手写 XML”,而是协调与委托。善用 writeObjectField、writeObject 等方法,让 Jackson 复用其成熟的序列化管道,既能保证字段完整性,又能兼容注解、泛型与多态机制。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

338

2023.08.02

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

232

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

437

2024.03.01

java多态详细介绍
java多态详细介绍

本专题整合了java多态相关内容,阅读专题下面的文章了解更多详细内容。

15

2025.11.27

java多态详细介绍
java多态详细介绍

本专题整合了java多态相关内容,阅读专题下面的文章了解更多详细内容。

15

2025.11.27

pdf怎么转换成xml格式
pdf怎么转换成xml格式

将 pdf 转换为 xml 的方法:1. 使用在线转换器;2. 使用桌面软件(如 adobe acrobat、itext);3. 使用命令行工具(如 pdftoxml)。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1894

2024.04.01

xml怎么变成word
xml怎么变成word

步骤:1. 导入 xml 文件;2. 选择 xml 结构;3. 映射 xml 元素到 word 元素;4. 生成 word 文档。提示:确保 xml 文件结构良好,并预览 word 文档以验证转换是否成功。想了解更多xml的相关内容,可以阅读本专题下面的文章。

2088

2024.08.01

xml是什么格式的文件
xml是什么格式的文件

xml是一种纯文本格式的文件。xml指的是可扩展标记语言,标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言。想了解更多相关的内容,可阅读本专题下面的相关文章。

1033

2024.11.28

Golang 性能分析与pprof调优实战
Golang 性能分析与pprof调优实战

本专题系统讲解 Golang 应用的性能分析与调优方法,重点覆盖 pprof 的使用方式,包括 CPU、内存、阻塞与 goroutine 分析,火焰图解读,常见性能瓶颈定位思路,以及在真实项目中进行针对性优化的实践技巧。通过案例讲解,帮助开发者掌握 用数据驱动的方式持续提升 Go 程序性能与稳定性。

9

2026.01.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WEB前端教程【HTML5+CSS3+JS】
WEB前端教程【HTML5+CSS3+JS】

共101课时 | 8.4万人学习

JS进阶与BootStrap学习
JS进阶与BootStrap学习

共39课时 | 3.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号