You need to enable JavaScript to run this app. Spring Boot REST接口Jackson多态序列化返回空JSON问题咨询
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot REST接口Jackson多态序列化返回空JSON问题咨询

问题根因

Jackson序列化多态结构时,默认以接口/方法上声明的静态类型作为序列化依据。由于MyData是空接口,不存在任何可序列化的属性,即便运行时实际传入的是带完整字段的MyDataType1、MyDataType2实例,也会因为类型识别逻辑的局限,最终输出空的JSON内容。

另外代码中存在两处容易引发空返回的语法问题需要先修正:

  • 接口路径的字符串多了一个引号:@GetMapping(value = "/my/path"") 会导致端点映射解析失败
  • 方法签名没有写完:public Map<String, Collection<? extends MyData>> get20062008Report( 缺少参数列表和方法体闭合,编译无法通过
序列化逻辑调整方案

方案1:在MyData接口上添加多态序列化注解(推荐)

这是Spring Boot环境下最通用、侵入性最低的实现方式,不需要修改全局Jackson配置,注解直接绑定类型映射关系:

@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.PROPERTY,
    property = "dataType"
)
@JsonSubTypes({
    @JsonSubTypes.Type(value = MyDataType1.class, name = "myDataType1"),
    @JsonSubTypes.Type(value = MyDataType2.class, name = "myDataType2")
})
public interface MyData {
}

配置说明:

  • 序列化时Jackson会自动识别对象的实际运行时类型,按照子类定义的属性规则输出JSON内容,不会再以空的MyData接口作为序列化基准
  • 每个输出的JSON对象会自动附带dataType标识字段,值为当前实例对应的子类标识名,后续前端反序列化、后端接收同类结构数据时,也可以依靠这个字段自动匹配对应的类
  • 标识名、携带的字段名都可以根据项目实际规则自定义

方案2:全局配置Jackson委托实际类型序列化

如果不想在接口上硬编码注解映射关系,可以通过自定义Jackson配置,强制跳过MyData的空类型判断,直接按照实际实例类型完成序列化:

@Configuration
public class JacksonMultiTypeConfig {
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer myDataTypeSerializerCustomizer() {
        return builder -> builder.modules(new SimpleModule()
            .addSerializer(MyData.class, new StdSerializer<MyData>(MyData.class) {
                @Override
                public void serialize(MyData value, JsonGenerator gen, SerializerProvider provider) throws IOException {
                    // 直接将序列化逻辑委托给当前对象的实际类型对应的序列化器
                    provider.defaultSerializeValue(value, gen);
                }
            })
        );
    }
}

这个方案的适用场景是如果存在大量类似的多态接口结构,可以统一复用这套委托逻辑,不需要逐个类添加注解。

常见避坑提示
  • 不要为了临时解决问题把返回值改成Object类型,虽然这种方式Jackson也能识别实际类型输出字段,但会丢失接口本身的类型约束,后续代码维护成本会大幅提升
  • 如果后续需要将前端传来的同结构JSON反序列化为对应的MyData子类,方案1的注解配置会自动支持反序列化的类型识别,不需要额外写转换逻辑
  • 配置完成后可以直接用单元测试验证序列化结果,不需要每次都启动服务调用接口调试

内容的提问来源于stack exchange,提问作者Nicolas Dupouy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.27 14:54:04