Spring Boot控制器中Jackson无法推导唯一Response子类型的解决方法
解决Jackson反序列化指定子类时的类型推断冲突问题
方案1:移除接口上的类型推断注解
如果业务场景中仅需直接使用具体实现类作为请求体参数,不需要通过接口做类型推断,可直接移除com.example.Response接口上的@JsonTypeInfo和@JsonSubTypes注解:
package com.example; public interface Response { String getInfo(); }
修改后Jackson会直接根据控制器参数指定的com.example.package1.Response类型完成反序列化,不再触发接口的子类型推断逻辑。
方案2:在请求体参数上显式指定反序列化类型
如果接口上的类型推断注解必须保留(比如其他接口参数场景需要依赖该逻辑),可在控制器的@RequestBody参数上添加@JsonDeserialize注解,强制指定反序列化的目标类:
@PostMapping fun start( @RequestBody @JsonDeserialize(as = com.example.package1.Response::class) response: com.example.package1.Response ): ResponseEntity<*> { // 业务代码 }
该注解会绕过接口层面的类型推断逻辑,直接使用指定类完成JSON反序列化。
问题原因
异常产生的核心逻辑:
com.example.Response接口标注了@JsonTypeInfo(use = DEDUCTION),Jackson会启用基于字段结构的子类型推断机制;com.example.package2.Response的number字段为可空的Integer类型,传入的{"info": "info"}JSON结构同时满足两个子类的字段要求(package2的类允许number缺失);- 即使控制器参数指定了具体子类,Jackson仍会先检查该类所属的接口是否启用了类型推断,进而尝试从接口的子类型列表中匹配,最终因匹配到多个候选类而抛出异常。
内容的提问来源于stack exchange,提问作者Stanislaw Slodyczka
相关产品推荐
相关产品推荐

