解决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)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月2日 06:21:24
下一篇 2025年12月2日 06:21:45

相关推荐

  • 什么是以太坊?2025最新版ETH与BTC对比分析

    以太坊与比特币,作为加密货币世界的两大支柱,各自承载着不同的设计理念和应用价值。虽然它们都基于区块链技术,但其核心功能、技术架构及生态系统存在显著差异。本篇文章将深入探讨以太坊的本质,并对比分析其与比特币在当前(假设为2025年最新状态)的主要特点。 以太坊的诞生与特性 1. 以太坊是一个开源的、基…

    2025年12月8日
    000
  • USDC是什么稳定币? 深入分析其安全性及USDT主要差异

    在数字资产世界中,价格波动是一个显著的特征。这种波动性,虽然为投机者提供了机会,但对于需要稳定价值储存或进行日常交易的用户而言,则带来了挑战。稳定币应运而生,旨在通过将其价值锚定于某种稳定资产(通常是法定货币,例如美元)来解决这一问题。usdc,即usd coin,是目前市场上广受关注的一种稳定币。…

    2025年12月8日
    000
  • 比特币交易信号如何识别?免费软件标注美元价格买卖点

    您是否在寻找一款能够帮助您识别比特币交易信号,并精确标注美元价格买卖点的软件?本文将为您详细介绍这样一款高效的交易辅助工具。这款软件旨在通过智能分析市场数据,为用户提供清晰的交易指引,帮助您更好地理解市场动态,把握交易时机。我们提供的下载链接均为官方渠道,确保您下载的是正版、安全的应用程序。点击本文…

    2025年12月8日
    000
  • 稳定币新手入门指南 手把手教你买卖USDT稳定币

    数字货币市场波动性显著,而稳定币的出现,为这一市场提供了一定的稳定性。usdt作为当前市值最大、应用最广的美元稳定币,对于初入数字资产领域的用户,理解并掌握其买卖方法至关重要。本指南旨在详细介绍usdt稳定币的基础知识及其具体的买卖流程。 稳定币USDT基础认知 1、什么是USDT稳定币 USDT,…

    2025年12月8日 好文分享
    000
  • 稳定币USDT前景如何_2025稳定币USDT价格会暴涨吗

    稳定币USDT前景如何_2025稳定币USDT价格会暴涨吗 usdt(tether)是目前全球使用最广泛的稳定币,其价值与美元1:1锚定,主要用于数字资产市场中的计价单位、交易媒介和资金避险工具。由于其流通量庞大、接受度广、流动性高,在全球加密资产交易中扮演着举足轻重的角色。许多投资者对usdt的未…

    2025年12月8日
    000
  • 稳定币USDC安全吗_USDC与USDT的区别在哪

    稳定币USDC安全吗_USDC与USDT的区别在哪 usdc是由美国公司circle与coinbase联合推出的美元稳定币,其核心目标是实现1:1锚定美元、保障资产安全、提升透明度。与市场占有率最高的usdt(tether)相比,usdc在设计机制、储备模式、监管路径等方面存在诸多差异。本文将围绕其…

    2025年12月8日
    000
  • 山寨币今日行情在哪里看?十大山寨币哪个平台最全?

    想要实时掌握山寨币行情,推荐使用CoinMarketCap、Binance必安、欧意OK等十大主流平台。想要实时掌握山寨币的最新行情,选择一个数据全面、更新及时的平台至关重要。本文整理了十大主流山寨币行情平台,按数据覆盖、更新速度、用户体验等维度进行对比,为您提供最实用的入口信息。 Top 10山寨…

    2025年12月8日 好文分享
    000
  • 安卓iOS版狗狗币多币种行情APP (支持BTC、ETH实时报价)

    欧意OK支持BTC、ETH、DOGE等主流币种行情和K线查看,数据同步快,界面简洁;2. Binance必安提供全球领先的交易量与完整行情数据及深度图、订单簿信息;3. 火必HTX支持多图表模式和自定义价格提醒;4. Gate.io大门支持超千种币种行情,更新迅速;5. CoinMarketCap提…

    2025年12月8日 好文分享
    000
  • 山寨币有哪些?2025十大潜力山寨币汇总(内附APP)

    2025年加密市场潜力山寨币有哪些?本文精选10大项目,涵盖AI+Web3、Layer2、模块化区块链等热门赛道。1.Arbitrum(ARB)是以太坊Layer2方案,具低费用和高吞吐量,上线欧意OK、Binance必安、火必HTX;2.Celestia(TIA)为模块化区块链数据可用性层,适配多…

    2025年12月8日 好文分享
    000
  • 狗狗币行情与BTC、ETH走势APP推荐(带K线、价格提醒功能)

    想掌握狗狗币、比特币、以太坊行情,推荐使用以下APP:1. Binance,功能专业,支持K线与提醒功能,适合交易用户;2. OK,操作流畅,提醒及时;3. TradingView,专业图表工具,适合技术分析;4. CoinMarketCap,界面简洁,适合初学者;5. CoinGecko,数据全面…

    2025年12月8日 好文分享
    000
  • TRX(波场)价格今日行情 (7月15日)最新价格行情

    TRX今日价格为$0.3002,约合2.1525¥,下跌1.48%,流通市值$284.47亿,全球占比0.78%,流通量94,760,105,914.81,24H成交额$8.73亿,换手率3.07%,流通市值排名第九;24H最高$0.305,最低$0.298891,振幅2.04%;昨日最高$0.30…

    2025年12月8日
    000
  • 以太坊 (ETH)是什么?与比特币有什么区别?以太坊全面解析

    数字货币领域,以太坊 (ethereum) 是一个引人注目的区块链平台。它不仅是一种加密货币,更是一个庞大的去中心化计算网络。其原生代币是以太币(eth),在整个网络中扮演着关键角色。以太坊的设计初衷是超越简单的价值转移,构建一个能够运行复杂应用程序的全球性平台。 以太坊是什么? 以太坊,作为一个开…

    2025年12月8日
    000
  • ADA(艾达币)价格今日行情 (7月15日)最新价格行情

    ADA今日价格为$0.7272,约合5.2143¥,跌幅-4.83%;流通市值$327.20亿,排名全球第10;24H成交额$11.92亿,换手率4.63%;24H最高$0.766390,最低$0.711387;近期价格波动较大,7天最高达$0.7759,最低$0.5731;ADA属于公链、智能合约…

    2025年12月8日
    000
  • SHIB价格今日行情 (7月15日)最新价格行情

    SHIB今日价格为$0.00001295,约合0.00009285¥,下跌6.9%。流通市值76.34亿美元,全球排名第19;24H成交额3.81亿,换手率4.99%;24H最高价$0.00001412,最低价$0.00001276;概念涵盖Memes、Robinhood上线及狗狗币概念;今日相关快…

    2025年12月8日
    000
  • SUI价格今日行情 (7月15日)最新价格行情

    SUI今日价格为$3.946,约合28.2947¥。涨跌幅为+2.16%,流通市值$394.60亿,全球排名第13;24H成交额$22.76亿,换手率16.70%;24H最高$3.9924,最低$3.8106;近7天、30天、90天的最高价分别为$3.9924、$3.9924、$4.2901,最低价…

    2025年12月8日
    000
  • 稳定币PYUSD安全吗_PayPal 推出PYUSD背后目的分析

    稳定币PYUSD安全吗_PayPal推出PYUSD背后目的分析 pyusd 是全球支付巨头 paypal 于 2023 年推出的 美元锚定型稳定币,由 paxos trust 公司负责发行与管理。该币种旨在将传统金融支付系统与区块链融合,实现稳定币在主流支付领域的应用。它的推出标志着全球金融科技企业…

    2025年12月8日
    000
  • USDT(泰达币)价格今日行情(7月15日)

    USDT当前价格为$0.9999,约合7.1697元。今日行情显示其涨跌幅为-0.02%,流通市值达$1618.03亿,全球总市值占比4.35%,流通量159,530,193,433.92,24H成交额54,909,243,338.96,换手率34.42%。24小时最高价$1.000098,最低价$…

    2025年12月8日
    000
  • 稳定币DAI是否安全_DAI崩盘过吗?稳定机制详解

    稳定币DAI是否安全_DAI崩盘过吗?稳定机制详解 dai 是由 makerdao 协议发行的 去中心化稳定币,不同于 usdt 或 usdc 等由中心化机构发行的稳定币,dai 完全基于智能合约运行,锚定1:1美元价值。由于其背后机制基于抵押资产与清算机制,dai 被认为是 defi 生态中最具代…

    2025年12月8日
    000
  • 稳定币USDC可以跨链吗_USDC支持哪些链与网络

    稳定币USDC可以跨链吗_USDC支持哪些链与网络 usdc 是由 circle 公司发行的 合规型美元稳定币,通过 1:1 美元资产储备进行锚定。其高透明度、合规背景以及多链部署能力,使得 usdc 成为继 usdt 后最具影响力的稳定币之一。是否支持跨链和可用在哪些区块链网络,是很多用户在使用 …

    2025年12月8日
    000
  • BNB(币安币)价格今日行情(7月15日)

    BNB当前价格为$685.66,约合4916.52¥,今日跌幅为-0.66%,流通市值达$955.05亿,全球总市值占比2.61%。1.BNB是币安发行的基于以太坊的数字资产,总量恒定2亿枚,每季度根据交易量销毁直至降至1亿枚;2.当前流通量为139,289,297.58,流通率69.64%,24H…

    2025年12月8日
    000

发表回复

登录后才能评论
关注微信