杰克逊多态性:如何将多个子类型映射到同一类

2022-09-03 13:45:28

我使用的是 Jackson 1.9.x。坚持以动物为例,这是我想做的:

假设我有一个动物类:

public class Animal {
    private String type;
    // accessors
}

public class Mammal extends Animal {
    private String diet;
    // accessors
}

public class Bird extends Animal {
    private boolean tropical;
    // accessors
}

我希望能够做这样的事情(我将几个子类型映射到一个类,并将几个子类型映射到另一个类):

@JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "type")
@JsonSubTypes({@JsonSubTypes.Type(value = Mammal.class, name = "Dog"),
                @JsonSubTypes.Type(value = Mammal.class, name = "Cat"),
                @JsonSubTypes.Type(value = Bird.class, name = "Dodo"},
                @JsonSubTypes.Type(value = Bird.class, name = "Cockatoo"})
public class Animal {

}

我现在看到的是,杰克逊只会识别狗到哺乳动物和渡渡鸟到鸟的映射。这是因为StdSubtypeResolver._collectAndResolve() 只允许同一类注册一次(由于 NamedType.equals()的实现)。

对于我看到的问题,是否有解决方法?


答案 1

我也遇到了同样的问题,发现子类型映射需要唯一的类。

我所做的是创建两个扩展同一基类的类。扩展类为空,因为它们具有与基类相同的属性。然后将其添加到子类型地图。例如,在您的情况下,它将是 -

@JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "type")
@JsonSubTypes({@JsonSubTypes.Type(value = Mammal.class, name = "Dog"),
            @JsonSubTypes.Type(value = Mammal.class, name = "Cat"),
            @JsonSubTypes.Type(value = BirdDodo.class, name = "Dodo"},
            @JsonSubTypes.Type(value = BirdCockatoo.class, name = "Cockatoo"})
public class Animal {

}

public class BirdCockatoo extends Cockatoo{}
public class BirdDodo extends Dodo{}

我知道这不是最好的方法,但在问题没有得到解决之前,这可能是解决这个问题的最佳方法。我现在遵循这种方法。

希望它能帮助你!


答案 2

该错误已在版本2.6.0中得到解决,因此您只需将Jackson更新到版本2.6.0或更高版本即可。其他信息在这里这里