使用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
相关产品推荐
相关产品推荐

