Java基于接口的JSON枚举反序列化失败及序列化异常问题
解决Jackson枚举实现接口的多态反序列化与序列化问题
问题原因分析
- 反序列化报错:你给接口
IA配置的多态类型信息要求rlType字段存储子类的类型名称(比如"B"),但JSON中该字段是枚举值"X",Jackson无法识别子类类型,因此抛出InvalidTypeIdException。 - 序列化输出数组:当枚举实现带多态配置的接口时,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
相关产品推荐
相关产品推荐

