当前位置: 首页 > 知识库问答 >
问题:

Jackson 3.1.1缺少列表多态类型的子类型异常的类型ID?

凤修为
2023-03-14

我有一个抽象类的具体对象。

我在抽象类和子类上使用注释,但JSON输出看起来不正确,而且我一直在反序列化上遇到异常

我还在学习杰克逊,不幸的是,很多关于这个主题的教程已经过时了。

以下是底部有我的对象映射器的类:

抽象类:

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, property = "BTRFSPhysicalLocationItem")
@JsonSubTypes({
    @Type(name = "Snapshot", value = Snapshot.class),
    @Type(name = "Backup", value = Backup.class),
    @Type(name = "Subvolume", value = Subvolume.class)})
public abstract class BTRFSPhysicalLocationItem {

    private final String name;
    @JsonProperty
    private final Path location;

    /**
     * Makes a new subvolume instance with the specified location. May or may
     * not actually exist.
     *
     * @param location The location of the subvolume
     */
    @JsonCreator
    protected BTRFSPhysicalLocationItem(@JsonProperty(value = "location") Path location) {
        this.location = location;
        this.name = location.getFileName().toString();
    }

混凝土等级:

public class Subvolume extends BTRFSPhysicalLocationItem {

    /**
     * Creates a new subvolume with the specified path.The subvolume may or may
     * not exist at this point.
     *
     * @param location
     */
    @JsonCreator
    public Subvolume(@JsonProperty Path location) {
        super(location);
    }

Objectmapper块:

ObjectMapper MAPPER = new ObjectMapper();
List<Subvolume> SUBVOLUME_LIST = new ArrayList<>();
//Subvolume is populated by other methods it's not worth showing them here
System.out.println("\n\n");
                MAPPER.writeValue(System.out, SUBVOLUME_LIST);
                System.out.println("\n\n\n");
                var s = MAPPER.writeValueAsString(SUBVOLUME_LIST);
                List<Subvolume> list = MAPPER.readValue(s, new TypeReference<List<Subvolume>>() {
                });

输出JSON:[{"name":"wanderingEcho","位置":"file:///home/sarah/NetBeansProjects/wanderingEcho/"}]

例外:

Aug 05, 2019 4:55:14 PM com.protonmail.sarahszabo.wanderingecho.btrfs.BTRFS <clinit>
SEVERE: null
com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Missing type id when trying to resolve subtype of [simple type, class com.protonmail.sarahszabo.wanderingecho.btrfs.subvolume.Subvolume]: missing type id property 'BTRFSPhysicalLocationItem'
 at [Source: (String)"[{"name":"WanderingEcho","location":"file:///home/sarah/NetBeansProjects/WanderingEcho/"}]"; line: 1, column: 89] (through reference chain: java.util.ArrayList[0])

其他答案(例如多态类型的Jackson反序列化)建议使用ObjectMapper方法,但根据我阅读的教程,这应该没有必要。

不知道我在注释上做错了什么。

共有1个答案

邢博文
2023-03-14

在您的json中,您缺少BTRFSP物理位置项目-想想看-Jackson应该如何知道您期望什么实现?

应该是这样的

[
    {
        "BTRFSPhysicalLocationItem": "Subvolume",
        "name": "WanderingEcho",
        "location":"file:///home/sarah/NetBeansProjects/WanderingEcho/"
    }
]

如果希望Jackson在序列化对象时包含该类型,还需要添加JsonTypeInfo。像属性作为包括作为@JsonTypeInfo注释的参数

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "BTRFSPhysicalLocationItem")

“编辑确定”似乎我已经解决了这个问题-您不生成属性的问题与Java类型的擦除有关,并在这里进行了详细描述。

TLDR;杰克逊对不可靠类型有问题-似乎<代码>列表

解决方案是创建一个将扩展ArrayList的帮助类

public class SubvolumeList extends ArrayList<Subvolume> {}

此外,您的代码中还有一些问题——一个是您应该使用use=JsonTypeInfo。如果您想按属性值(如子卷)而不是包/类字符串文字进行反序列化,请在@JsonTypeInfo中输入ID. NAME

其次,您应该在参数列表中命名JsonProperty,如JsonProperty(value=“location”)

 类似资料: