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

Java基于接口的JSON枚举反序列化失败及序列化异常问题

解决Jackson枚举实现接口的多态反序列化与序列化问题

问题原因分析

  1. 反序列化报错:你给接口IA配置的多态类型信息要求rlType字段存储子类的类型名称(比如"B"),但JSON中该字段是枚举值"X",Jackson无法识别子类类型,因此抛出InvalidTypeIdException。
  2. 序列化输出数组:当枚举实现带多态配置的接口时,Jackson默认会同时序列化类型id和枚举值,导致输出["B","X"]这样的数组结构。

解决方案

1. 调整多态类型配置,指定默认实现

给IA的@JsonTypeInfo添加defaultImpl属性,指定当找不到类型id时默认用B类解析,这样Jackson会把rlType字段的枚举值直接映射为B的实例:

@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.PROPERTY,
        property = "rlType",
        defaultImpl = B.class // 添加默认实现类
)
@JsonSubTypes({
        @JsonSubTypes.Type(value = B.class, name = "B") // 给B指定类型名称
})
public interface IA {
}

2. 修正枚举的序列化行为

去掉B上的@JsonTypeInfo(use = JsonTypeInfo.Id.NONE),添加@JsonValue注解让枚举序列化时只输出自身名称,避免生成数组:

public enum B implements IA {
    X, Y, Z;

    @JsonValue
    public String getName() {
        return this.name();
    }
}

3. 修正测试代码的笔误

测试代码中RateLimiterSettings应为Settings:

@Test
void testDeserialization() throws Exception {
    String json = """
        {
            "rlType": "X",
            "myint1": 5,
            "myint2": 10
        }
    """;
    ObjectMapper objectMapper = new ObjectMapper();
    Settings settings = objectMapper.readValue(json, Settings.class);
}

效果验证

  • 反序列化:Jackson会自动使用B类解析"X",成功得到B.X实例,不再抛出类型id异常。
  • 序列化:Settings对象的rlType字段会输出"X",而非数组结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 15:52:47