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

使用Jackson反序列化接口时遇类型解析错误,求助原因

问题原因分析及解决思路

错误核心原因

  • 类型继承关系不匹配:Cat、Dog直接实现Animal接口,AnimalRequest是另一个独立实现Animal的密封类,二者属于平级的Animal实现类,无继承关系。但CreateAnimalDto的animals字段声明为List<AnimalRequest>,Jackson尝试将JSON中的cat/dog类型反序列化为AnimalRequest的子类型,自然无法匹配。
  • 类型标识绑定错位:你在Animal接口上配置的@JsonSubTypes是绑定Animal的子类型(Cat/Dog),但反序列化目标是AnimalRequest类型,Jackson无法将Animal的子类型识别为AnimalRequest的子类型。

修复方案

方案一:调整继承结构,让Cat/Dog继承AnimalRequest

修改Cat和Dog的定义,使其继承AnimalRequest而非直接实现Animal:

class Dog(
    private val dogSpecificField: String,
    override val id: UUID,
    override val index: Int
) : AnimalRequest(id), Animal {
    override val type: AnimalType = AnimalType.DOG
}

class Cat(
    private val catSpecificField: String,
    override val id: UUID,
    override val index: Int
) : AnimalRequest(id), Animal {
    override val type: AnimalType = AnimalType.CAT
}

同时将@JsonTypeInfo和@JsonSubTypes注解移至AnimalRequest类上:

@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME, 
    include = JsonTypeInfo.As.PROPERTY, 
    property = "type"
)
@JsonSubTypes(
    value = [
        JsonSubTypes.Type(value = Dog::class, name = "dog"),
        JsonSubTypes.Type(value = Cat::class, name = "cat")
    ]
)
sealed class AnimalRequest(
    val id: UUID,
) : Animal

方案二:修改DTO列表类型为List<Animal>

若无需AnimalRequest作为中间类型,可直接将CreateAnimalDto的animals字段改为List<Animal>:

@JsonInclude(JsonInclude.Include.ALWAYS)
data class CreateAnimalDto(
    val name: String,
    val animals: List<Animal>
)

这样Jackson就能依据Animal接口上的类型标识,正确将JSON反序列化为Cat或Dog实例。

内容的提问来源于stack exchange,提问作者four-eyes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 10:05:13