解决Jackson YAML序列化中多态类型标签的显示问题

解决Jackson YAML序列化中多态类型标签的显示问题

本文旨在解决使用jackson进行多态类yaml序列化时,输出中出现不必要的原生类型标签(如`!`)的问题。我们将深入探讨该现象产生的原因,并提供一种通过配置`yamlmapper`禁用特定`yamlgenerator.feature`来有效移除这些标签的方法,从而实现与json序列化一致的简洁输出。

在Java开发中,Jackson库是处理JSON和YAML序列化与反序列化的强大工具。当涉及到多态类型的序列化时,我们通常会利用@JsonTypeInfo和@JsonSubTypes注解来指定类型信息如何嵌入到输出中。例如,我们可以选择将类型信息作为现有属性(JsonTypeInfo.As.EXISTING_PROPERTY)来表示,这在JSON输出中表现良好,能够生成简洁且易于理解的结构。然而,在使用jackson-dataformat-yaml进行YAML序列化时,即使已指定类型信息作为现有属性,输出中仍可能出现额外的原生YAML类型标签,如!或!,这与我们期望的简洁输出不符。

理解问题现象

考虑以下一组Java类,它们定义了一个多态的Vehicle接口及其实现类Car和Truck,以及一个包含Vehicle列表的Vehicles容器类。我们使用type属性作为类型标识符。

import com.fasterxml.jackson.annotation.JsonCreator;import com.fasterxml.jackson.annotation.JsonProperty;import com.fasterxml.jackson.annotation.JsonSubTypes;import com.fasterxml.jackson.annotation.JsonTypeInfo;import com.fasterxml.jackson.core.JsonProcessingException;import com.fasterxml.jackson.databind.ObjectMapper;import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;import com.google.common.collect.ImmutableList;import lombok.Value;import java.util.List;import static java.util.Objects.requireNonNull;public class PolymorphicSerializationExample {    @JsonTypeInfo(use = JsonTypeInfo.Id.NAME,        include = JsonTypeInfo.As.EXISTING_PROPERTY,        property = "type")    @JsonSubTypes({        @JsonSubTypes.Type(value = Car.class, name = "car"),        @JsonSubTypes.Type(value = Truck.class, name = "truck") })    public interface Vehicle {        String getName();    }    @Value    public static class Car implements Vehicle {        String name;        String type = "car"; // 类型信息作为现有属性        @JsonCreator        public Car(@JsonProperty("name") final String name) {            this.name = requireNonNull(name);        }    }    @Value    public static class Truck implements Vehicle {        String name;        String type = "truck"; // 类型信息作为现有属性        @JsonCreator        public Truck(@JsonProperty("name") final String name) {            this.name = requireNonNull(name);        }    }    @Value    public static class Vehicles {        List vehicles;        @JsonCreator        public Vehicles(@JsonProperty("vehicles") final List vehicles) {            super();            this.vehicles = requireNonNull(vehicles);        }    }    public static void main(String[] args) throws JsonProcessingException {        ObjectMapper MAPPER = new ObjectMapper(); // JSON Mapper        ObjectMapper YAML_MAPPER = YAMLMapper.builder()            .disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER) // 禁用文档开始标记            .build(); // YAML Mapper        final Vehicles vehicles = new Vehicles(ImmutableList.of(new Car("Dodge"), new Truck("Scania")));        // 序列化为JSON        final String json = MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(vehicles);        System.out.println("--- JSON Output ---");        System.out.println(json);        // 序列化为YAML        final String yaml = YAML_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(vehicles);        System.out.println("n--- YAML Output (Problematic) ---");        System.out.println(yaml);    }}

运行上述代码,我们将得到如下输出:

--- JSON Output ---{  "vehicles" : [ {    "name" : "Dodge",    "type" : "car"  }, {    "name" : "Scania",    "type" : "truck"  } ]}--- YAML Output (Problematic) ---vehicles:- !  name: "Dodge"  type: "car"- !  name: "Scania"  type: "truck"

可以看到,JSON输出非常干净,没有额外的类型信息。然而,YAML输出中却出现了!和!这样的原生YAML标签,这增加了输出的冗余性,并且可能不是我们期望的格式。

解决方案:禁用原生类型ID特性

造成YAML输出中出现这些原生类型标签的原因是jackson-dataformat-yaml库中的一个默认特性:YAMLGenerator.Feature.USE_NATIVE_TYPE_ID。当此特性启用时,Jackson会尝试使用YAML的原生标签机制来表示多态对象的类型信息。尽管我们已经通过@JsonTypeInfo(include = JsonTypeInfo.As.EXISTING_PROPERTY)将类型信息嵌入到了对象的一个属性中,YAMLGenerator仍然会额外地生成这些原生标签。

Seede AI Seede AI

AI 驱动的设计工具

Seede AI 586 查看详情 Seede AI

要解决这个问题,只需在构建YAMLMapper时显式禁用YAMLGenerator.Feature.USE_NATIVE_TYPE_ID特性即可。

import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;import com.fasterxml.jackson.databind.ObjectMapper;// ... 其他导入public class PolymorphicSerializationExample {    // ... Vehicle, Car, Truck, Vehicles 类定义    public static void main(String[] args) throws JsonProcessingException {        ObjectMapper MAPPER = new ObjectMapper();        // 修正后的YAML Mapper配置        ObjectMapper YAML_MAPPER = YAMLMapper.builder()            .disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER)            .disable(YAMLGenerator.Feature.USE_NATIVE_TYPE_ID) // 禁用原生类型ID特性            .build();        final Vehicles vehicles = new Vehicles(ImmutableList.of(new Car("Dodge"), new Truck("Scania")));        final String json = MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(vehicles);        System.out.println("--- JSON Output ---");        System.out.println(json);        final String yaml = YAML_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(vehicles);        System.out.println("n--- YAML Output (Corrected) ---");        System.out.println(yaml);    }}

验证修正后的输出

重新运行修改后的代码,我们将得到期望的YAML输出:

--- JSON Output ---{  "vehicles" : [ {    "name" : "Dodge",    "type" : "car"  }, {    "name" : "Scania",    "type" : "truck"  } ]}--- YAML Output (Corrected) ---vehicles:- name: "Dodge"  type: "car"- name: "Scania"  type: "truck"

可以看到,!和!这样的原生YAML类型标签已经被成功移除,YAML输出变得与JSON输出一样简洁,且类型信息仍通过type属性正确地保留。

总结

当使用Jackson进行多态对象的YAML序列化,并且希望避免输出中出现原生YAML类型标签(如!)时,关键在于禁用YAMLGenerator.Feature.USE_NATIVE_TYPE_ID特性。这个特性默认是启用的,它指示Jackson使用YAML的原生机制来表示类型。通过将其禁用,我们确保了即使在多态场景下,YAML输出也能保持简洁,尤其是在类型信息已通过@JsonTypeInfo.As.EXISTING_PROPERTY等方式嵌入到对象属性中的情况下,这提供了与JSON序列化一致的输出风格。理解并正确配置YAMLGenerator的特性,有助于我们更好地控制YAML输出的格式和内容,满足特定的应用需求。

以上就是解决Jackson YAML序列化中多态类型标签的显示问题的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1068240.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
如何通过cssword-wrap控制文字换行
上一篇 2025年12月2日 06:21:29
三星 Galaxy Z Fold6 手机通过 FCC 认证:支持 5G、Wi-Fi 5.8GHz、UWB
下一篇 2025年12月2日 06:21:36

相关推荐

  • 动态内省Java类中的Jackson @JsonNaming 策略

    本文探讨了在Java中进行泛型数据反序列化时,如何动态地获取类上通过@JsonNaming注解设置的PropertyNamingStrategy。通过利用Jackson的SerializationConfig、BeanDescription和JacksonAnnotationIntrospector…

    2026年8月25日
    000
  • 三星启动1nm工艺研发 2029年后量产

    三星抢先布局1nm芯片工艺,力争超越台积电!据报道,三星电子已启动1nm(纳米)晶圆代工工艺研发,目标于2029年后实现量产。此举旨在弥补目前在2nm工艺等方面与台积电的差距,力图实现技术反超。 ☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜…

    2026年8月25日
    000
  • 电脑丢失dll文件软件无法运行怎么办 解决方法在这里

    电脑丢失dll文件软件无法运行怎么办 解决方法在这里电脑丢失dll文件软件无法运行怎么办 解决方法在这里电脑丢失dll文件软件无法运行怎么办 解决方法在这里电脑丢失dll文件软件无法运行怎么办 解决方法在这里

    当你启动某个软件时,系统突然弹出警告:“由于计算机中缺少xxx.dll,无法运行此程序。建议重新安装该程序以修复问题。”这类提示对不少用户而言早已司空见惯。dll文件(即动态链接库)在windows操作系统中至关重要,一旦丢失或损坏,便可能导致应用程序无法正常加载。本文将为你提供几种高效可行的解决方…

    2026年8月25日 用户投稿
    000
  • windows怎么重启网卡

    windows怎么重启网卡windows怎么重启网卡windows怎么重启网卡windows怎么重启网卡

    最直接重启Windows网卡的方法是通过网络连接或设备管理器禁用再启用,可解决IP冲突、驱动卡顿等临时故障。具体操作包括:图形界面中进入“更改适配器选项”右键禁用/启用网卡;或通过设备管理器对网络适配器执行相同操作。高级用户可使用命令行工具自动化处理,如netsh命令或PowerShell cmdl…

    2026年8月25日 用户投稿
    000
  • 告别文件类型识别难题:adrienrn/php-mimetyper助你轻松搞定MIME类型

    最近在开发一个文件上传和下载相关的模块时,我遇到了文件类型识别的问题。我需要根据文件的扩展名来判断其 MIME 类型,以便正确地处理这些文件。然而,我发现 PHP 内置的函数或者一些简单的库并不能提供足够准确和全面的 MIME 类型映射。一些文件类型的识别不够准确,而且缺少对一些常见文件类型的支持。…

    用户投稿 2026年8月25日
    300
  • Java中HashMap的工作原理是什么 图解Java HashMap的存储结构和哈希机制

    Java中HashMap的工作原理是什么 图解Java HashMap的存储结构和哈希机制Java中HashMap的工作原理是什么 图解Java HashMap的存储结构和哈希机制Java中HashMap的工作原理是什么 图解Java HashMap的存储结构和哈希机制Java中HashMap的工作原理是什么 图解Java HashMap的存储结构和哈希机制

    java hashmap通过哈希表实现键值对的高效存储与检索,其底层结构为数组加链表(或红黑树),1. 哈希函数将键转换为数组索引以定位存储位置;2. 使用链地址法解决哈希冲突,jdk 1.8后引入红黑树优化长链表查找效率;3. put操作包括计算哈希、定位桶、处理冲突及扩容判断;4. get操作通…

    2026年8月25日 用户投稿
    600
  • 如何用免费工具做商务PPT_免费商务PPT制作的实用方法

    使用免费工具制作专业商务PPT,首选WPS Office在线版,提供丰富模板并支持云同步;其次利用AiPPT的AI功能,输入主题即可自动生成完整大纲,提升效率;再通过iSlide插件优化设计,实现配色统一、图表智能转换与布局校正;最后可选Canva可画,以拖拽方式快速编辑高颜值幻灯片,支持多尺寸适配…

    2026年8月25日
    000
  • c盘空间满了怎样清理 5个实用清理方法推荐

    c盘空间满了怎样清理 5个实用清理方法推荐c盘空间满了怎样清理 5个实用清理方法推荐c盘空间满了怎样清理 5个实用清理方法推荐c盘空间满了怎样清理 5个实用清理方法推荐

    c盘作为系统盘,承载着操作系统和众多软件的安装数据,一旦空间不足,不仅会拖慢系统运行速度,还可能导致部分程序无法正常使用。那么,当c盘被占满时该如何清理?本文将提供五种实用方法,助你快速释放c盘空间,提升电脑性能。 一、利用Windows内置磁盘清理功能 Windows系统自带了磁盘清理工具,可以帮…

    2026年8月25日 用户投稿
    300
  • 使用Xdebug进行代码调试

    使用xdebug可以显著提升php代码调试效率。1) 安装xdebug,通常通过pecl完成。2) 在php.ini中配置xdebug。3) 使用phpstorm进行调试。4) 设置断点,逐步执行代码,检查变量。5) 使用堆栈跟踪和代码覆盖率分析功能。注意xdebug的性能开销和配置复杂性,结合日志…

    2026年8月25日
    000
  • kimichat官网入口地址推荐-kimichat官方网站网址导航

    Kimi智能助手官网为https://kimi.moonshot.cn/,由北京月之暗面科技有限公司推出,支持20万汉字上下文输入,具备联网搜索、文件解析、多语言翻译、代码编写、内容创作及角色扮演等功能,适用于学术研究、内容创作、金融分析、法律工作等场景,提供高效智能服务。 ☞☞☞AI 智能聊天, …

    2026年8月25日
    000
  • 苹果官方预告M5芯片:新MacBook Pro首发 本周亮相

    10月15日消息,苹果公司营销主管格雷格・乔斯维亚克(greg joswiak)发布了一则官方预告,透露即将推出重磅新品。 其发布的宣传动画中出现了一个明显的“V”字形图案(对应罗马数字5),同时配文连续使用了五个“M”,几乎直接揭示了新品的关键信息——苹果M5芯片。 据多方爆料,新款MacBook…

    2026年8月25日
    000
  • 怎么在抖音上弄小程序点单,全攻略讲解

    引言: 在移动互联网迅猛发展的今天,线上点单已成为商家提升服务效率、增强客户粘性的重要手段。作为国内极具影响力的短视频平台,抖音不仅拥有庞大的流量池,还推出了功能完善的小程序系统,让商家可以轻松搭建专属的点单入口。本文将为您全面解析如何在抖音实现小程序点单功能,手把手教您完成从注册到上线的全流程。 …

    2026年8月25日
    000
  • Java中对象流怎么使用 掌握Java序列化对象的读写方法

    Java中对象流怎么使用 掌握Java序列化对象的读写方法Java中对象流怎么使用 掌握Java序列化对象的读写方法Java中对象流怎么使用 掌握Java序列化对象的读写方法Java中对象流怎么使用 掌握Java序列化对象的读写方法

    java对象流用于序列化和反序列化,即将对象转换为字节流以实现存储或传输。1. 要实现序列化,类需实现serializable接口并建议显式声明serialversionuid;2. 使用objectoutputstream将对象写入输出流完成序列化;3. 使用objectinputstream从输…

    2026年8月25日 用户投稿
    000
  • win8怎么映射网络驱动器 win8添加映射网络驱动器操作步骤

    首先通过计算机管理界面映射网络驱动器,选择驱动器字母并输入共享路径,勾选登录时重新连接以实现开机自动挂载;其次可使用命令行执行net use命令快速映射,支持指定用户名密码及持久化连接;最后还可从网络位置直接右键共享文件夹进行映射,三步操作均需完成凭据认证。 如果您尝试在Windows 8系统中访问…

    2026年8月25日
    000
  • DeepCoder-14B-Preview— Agentica 联合 Together AI 开源的代码生成模型

    deepcoder-14b-preview:一款开源的140亿参数代码生成模型 Agentica和Together AI联合发布了DeepCoder-14B-Preview,这是一个基于Deepseek-R1-Distilled-Qwen-14B微调的大型代码生成模型。该模型采用分布式强化学习(RL…

    2026年8月25日
    000
  • 定制VS通用软件:谁更适合您的企业?

    在当今数字化时代,选择合适的软件解决方案已成为企业提升运营效率、增强市场竞争力的核心环节。面对“定制企业软件”与“通用现成软件”的抉择,企业必须深入权衡各自的优劣,才能找到真正契合自身发展路径的技术支撑。 多维对比:关键指标深度剖析 1. 功能匹配度 定制企业软件:最大优势在于精准贴合。系统从零构建…

    2026年8月25日
    200
  • Java中Semaphore和Exchanger的应用场景解析

    Java中Semaphore和Exchanger的应用场景解析Java中Semaphore和Exchanger的应用场景解析Java中Semaphore和Exchanger的应用场景解析Java中Semaphore和Exchanger的应用场景解析

    semaphore和exchanger在java并发编程中各司其职。1. semaphore用于控制对共享资源的访问数量,适用于资源池限制、有界队列等场景;2. exchanger用于两个线程之间的数据交换,适用于生产者-消费者模型中直接交换数据的场景。semaphore通过acquire()和re…

    2026年8月25日 用户投稿
    000
  • 电脑死机了按什么键恢复 快速解决电脑死机问题

    电脑死机了按什么键恢复 快速解决电脑死机问题电脑死机了按什么键恢复 快速解决电脑死机问题电脑死机了按什么键恢复 快速解决电脑死机问题电脑死机了按什么键恢复 快速解决电脑死机问题

    电脑死机时,屏幕突然变黑,鼠标无法移动,键盘也毫无反应,常常让人不知所措。面对这种情况,若不清楚该如何操作,焦虑感往往会加剧。本文将为你提供几种实用的应对方法,帮助你在电脑卡死时快速恢复正常使用。 一、通过快捷键强制结束无响应程序 电脑死机多数是由于某个程序卡住或过度占用系统资源所致。此时,你可以使…

    2026年8月25日 用户投稿
    100
  • 西瓜视频PC版广告太多怎么屏蔽_西瓜视频PC版减少广告骚扰设置方法

    使用官方方法减少广告最安全,登录账号参与活动可获去广体验,完成学生认证享会员折扣,网页端开启弹窗拦截与关闭个性化推荐,避免用第三方插件以防风险。 想在电脑上看西瓜视频少点广告,直接用官方方法最稳妥。第三方工具或破解版风险高,容易中病毒或者被封号,不值得。 使用官方功能减少广告 西瓜视频PC端本身没有…

    2026年8月25日
    200
  • win11任务栏图标不合并怎么设置_Win11任务栏窗口取消合并与显示标签

    1、通过注册表编辑器将TaskbarGlomLevel设为2,可取消任务栏图标合并;2、使用组策略编辑器启用“从不合并任务栏按钮”策略;3、借助ExplorerPatcher等第三方工具关闭图标合并,实现窗口独立显示。 如果您希望在使用Windows 11时更方便地区分打开的多个窗口,可以调整任务栏…

    2026年8月25日
    000

发表回复

登录后才能评论
关注微信