使用XmlMapper时如何解决Jackson List反序列化错误?
问题:XmlMapper解析时抛出InvalidTypeIdException错误
错误信息
com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve type id 'accounts' as a subtype of `java.util.List<Account>`: no such class found at [Source: (StringReader); line: 48, column: 11] (through reference chain: >Partner["accounts"])
我的尝试代码
Partner类
@JsonIdentityInfo( generator = ObjectIdGenerators.PropertyGenerator.class, property = "databaseId") @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") @JsonSubTypes({ @JsonSubTypes.Type(value = java.util.List.class, name = "accounts") }) public class Partner{ private List<Account> accounts; @JsonManagedReference public void setAccounts(List<Account> accounts) { this.accounts = accounts; }}
映射器配置
mapper.activateDefaultTyping(mapper.getPolymorphicTypeValidator(),ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_OBJECT); mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY); mapper.configure(SerializationFeature.INDENT_OUTPUT, true); mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS z"); df.setTimeZone(TimeZone.getTimeZone("UTC")); mapper.setDateFormat(df); mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
解决方案
问题根源
- 多态注解误用:给
Partner类添加的@JsonTypeInfo和@JsonSubTypes是用于类自身的多态继承场景,不适用于accounts这个集合属性,这会让Jackson错误地将accounts识别为Partner的子类型,导致解析失败。 - 全局类型配置冲突:
activateDefaultTyping开启了全局非final类型的多态类型标识,和手动指定的accounts类型名冲突,进一步触发错误。
修复步骤
- 移除Partner类上的多余多态注解:删除
@JsonTypeInfo和@JsonSubTypes,Partner本身不需要多态处理,accounts作为普通集合属性无需这些注解。 - 调整映射器配置(按需选择):
- 如果业务不需要全局多态类型支持,直接删除
activateDefaultTyping这一行配置; - 若必须保留全局配置,可给
accounts字段单独添加@JsonTypeInfo来覆盖全局规则,但更简洁的方式是移除全局默认类型激活,除非有其他多态类需要处理。
- 如果业务不需要全局多态类型支持,直接删除
修改后的Partner类
@JsonIdentityInfo( generator = ObjectIdGenerators.PropertyGenerator.class, property = "databaseId") public class Partner { private List<Account> accounts; @JsonManagedReference public void setAccounts(List<Account> accounts) { this.accounts = accounts; } // 补充getter方法,Jackson解析需要读取属性 public List<Account> getAccounts() { return accounts; } }
额外注意
如果XML结构中accounts节点包含多个account子节点,可添加XML专用注解确保节点匹配:
@JacksonXmlElementWrapper(localName = "accounts") @JacksonXmlProperty(localName = "account") private List<Account> accounts;
内容的提问来源于stack exchange,提问作者creationk
相关产品推荐
相关产品推荐

