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

Java JSON多态反序列化失败求助:已尝试@Json相关注解仍报错

问题描述

尝试将JSON文件反序列化为Java类,试过@JsonSubTypes、@JsonTypeInfo以及CLASS、NAME等各类配置,均未成功。JSON中data数组的元素可以是Error或Group类型,对应Java中的ExceptionItem抽象子类。

原始JSON

{
  "data": [
    {
        "error_msg": "error msg 1",
        "error_code": "error code 1",
        "type": "error"
    },
    {
        "data": [
          {
            "error_msg": "error msg 2",
            "error_code": "error code 2",
            "type": "error"
          }
        ],
        "name": "group1",
        "type": "group"
     }
  ],
  "name": "exceptions_db",
  "version": "1"
}

Java类定义

ExceptionsModel

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class ExceptionsModel implements JsonModel{
    private String version;
    private String name;
    private List<ExceptionItem> data;

    public void setData(List<ExceptionItem> data) {
        if (data.size() < 1) {
            throw new IllegalArgumentException("Data array must contain at least one item");
        }
        this.data = data;
    }
}

Error

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Error extends ExceptionItem {
    private String error_msg;
    private String error_code;
}

Group

@Getter
@Setter
@NoArgsConstructor
public class Group extends ExceptionItem {
    private String name;
    private List<ExceptionItem> data;

    public Group(String name, List<ExceptionItem> data) {
        if (data.size() < 1) {
            throw new IllegalArgumentException("Data array must contain at least one item");
        }
        this.name = name;
        this.data = data;
    }

    public void setData(List<ExceptionItem> data) {
        if (data.size() < 1) {
            throw new IllegalArgumentException("Data array must contain at least one item");
        }
        this.data = data;
    }
}

ExceptionItem(初始版本)

public abstract class ExceptionItem {
}

已尝试的注解配置(无效)

为ExceptionItem添加Jackson类型注解后,仍然报错:

@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY, property="type")
@JsonSubTypes({
        @JsonSubTypes.Type(value = Error.class, name = "error"),
        @JsonSubTypes.Type(value = Group.class, name = "group"),
})
public abstract class ExceptionItem {
}

报错信息

Can not construct instance of com.altair.infrastructures.propertiesFile.jsonResourceLoader.exceptions.ExceptionItem, problem: abstract types can only be instantiated with additional type information
at [Source: C:\QA\TestCaseGenerator\systemFiles\exceptions\Exceptions_DB.json; line: 3, column: 5] (through reference chain: com.altair.infrastructures.propertiesFile.jsonResourceLoader.exceptions.ExceptionsModel["data"])


解决方案

问题出在@JsonTypeInfo的use参数配置错误:

  • 当前使用JsonTypeInfo.Id.CLASS,Jackson会期望type字段的值是类的全限定名(比如com.example.Error),但你的JSON中type是error、group这类自定义标识,不匹配。
  • 需要将use改为JsonTypeInfo.Id.NAME,让Jackson通过name值匹配@JsonSubTypes中定义的子类。

修正后的ExceptionItem类:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
        @JsonSubTypes.Type(value = Error.class, name = "error"),
        @JsonSubTypes.Type(value = Group.class, name = "group")
})
public abstract class ExceptionItem {
}

额外检查项:

  • 确认Jackson版本为2.x及以上,旧版本可能不支持部分注解特性
  • 验证Lombok的@Getter/@Setter是否正常生成方法,避免因缺少访问器导致反序列化失败
  • 确保反序列化使用的ObjectMapper未禁用类型解析功能

内容的提问来源于stack exchange,提问作者Gilad Dahan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 09:07:06