Java 如何使用Jackson反序列化泛型类?

Java 如何使用Jackson反序列化泛型类?,java,json,generics,jackson,json-deserialization,Java,Json,Generics,Jackson,Json Deserialization,我有这样一些课程: @JsonIgnoreProperties(ignoreUnknown=true) @JsonSubTypes( { @JsonSubTypes.Type(value=LionCage.class,name=“LION”), @JsonSubTypes.Type(value=TigerCage.class,name=“TIGER”), } ) @JsonTypeInfo(use=JsonTypeInfo.Id.NAME,include=JsonTypeInfo.As.PROP

我有这样一些课程:

@JsonIgnoreProperties(ignoreUnknown=true)
@JsonSubTypes(
{
@JsonSubTypes.Type(value=LionCage.class,name=“LION”),
@JsonSubTypes.Type(value=TigerCage.class,name=“TIGER”),
}
)
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME,include=JsonTypeInfo.As.PROPERTY,PROPERTY=“type”)
公共抽象类框架{
私有动物型;
私人动物;
}
公共枚举动物类型{
狮子,老虎
}
公共狮笼{
公共狮子座(){
超级(动物型狮子);
}
}
公狮{
私人内部管理长度;
}
公立动物园{
私有列表>();
}
现在,如果我尝试执行以下操作:

String json=“{cages:[{\'type\':\'LION\',\'animal\':{\'manelelength\':10}]}”;
ObjectMapper om=新的ObjectMapper();
Cage-Cage=om.readValue(json,Zoo.class);
笼中的第一个值应为
LionCage
类型,并且为

问题是
cages.get(0).getAnimal()
返回一个
LinkedHashMap
如何使它返回正确的
Animal
子类

我正在使用Jackson 1。


谢谢

对于您的
列表
问题,这是您希望使用原始类型的一次。将
Cage
类型参数声明为原始参数,而不是用通配符参数化

public class Zoo {

    private List<Cage> cages = new LinkedList<Cage>();
    // ... getters and setters similarly
}
杰克逊将能够确定
动物
狮子

通过
类型
它将知道它是一个
LionCage
,并通过

public LionCage extends Cage<Lion>{
印刷品

class com.spring.LionCage
com.spring.Lion@15d16efc
10

我认为您应该通过删除不必要的类型和使用
JsonTypeInfo.As.EXTERNAL\u属性
而不是
JsonTypeInfo.As.PROPERTY
来简化您的解决方案。使用
JsonTypeInfo.As.EXTERNAL\u属性
不必创建
Cage
子类。而且您根本不必创建
AnimalType
。POJO类可以如下所示:

@JsonIgnoreProperties(ignoreUnknown = true)
class Cage<ANIMAL> {

    @JsonSubTypes({
        @JsonSubTypes.Type(value = Lion.class, name = "LION"),
        @JsonSubTypes.Type(value = Tiger.class, name = "TIGER")
    })
    @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "type")
    private ANIMAL animal;

    public ANIMAL getAnimal() {
        return animal;
    }

    public void setAnimal(ANIMAL animal) {
        this.animal = animal;
    }

    @Override
    public String toString() {
        return "Cage [animal=" + animal + "]";
    }
}

class Lion {

    private int maneLength;

    public int getManeLength() {
        return maneLength;
    }

    public void setManeLength(int maneLength) {
        this.maneLength = maneLength;
    }

    @Override
    public String toString() {
        return "Lion [maneLength=" + maneLength + "]";
    }
}

class Tiger {

    private int length;

    public int getLength() {
        return length;
    }

    public void setLength(int length) {
        this.length = length;
    }

    @Override
    public String toString() {
        return "Tiger [maneLength=" + length + "]";
    }
}
以上代码打印:

Cage [animal=Lion [maneLength=10]]
Cage [animal=Tiger [maneLength=11]]

我没有用
Jackson
1.X测试我的解决方案,但我希望它能对你有用。

你能把你的getter和setter也放进去吗
问题是cage.getAnimal()返回一个LinkedHashMap
,考虑到
animal
是一个
animal
@SotiriosDelimanolis它是
公共动物getAnimal()
,它看起来很奇怪<代码>动物不是一个类。它是一种泛型“类型”,非常类似于
Map
中的
K
V
。您完全正确,遗漏了
Animal
作为类型变量。这就是我的JSON的外观。Jackson没有正确地将其反序列化。试试看。@Adam Aha,我过会儿再打给你。(考虑升级。)@Adam它与Jackson 1一样工作。我已经发布了确切的代码(这是您的+getter/setter),以便您进行验证。杰克逊1.9.13.谢谢你的帮助。你是对的,这是有效的。我的问题是收集动物。我做了更多的测试,发现了问题所在。我已经相应地修改了这个问题。@Adam我已经编辑了我的答案。替换
列表
@JsonIgnoreProperties(ignoreUnknown = true)
class Cage<ANIMAL> {

    @JsonSubTypes({
        @JsonSubTypes.Type(value = Lion.class, name = "LION"),
        @JsonSubTypes.Type(value = Tiger.class, name = "TIGER")
    })
    @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "type")
    private ANIMAL animal;

    public ANIMAL getAnimal() {
        return animal;
    }

    public void setAnimal(ANIMAL animal) {
        this.animal = animal;
    }

    @Override
    public String toString() {
        return "Cage [animal=" + animal + "]";
    }
}

class Lion {

    private int maneLength;

    public int getManeLength() {
        return maneLength;
    }

    public void setManeLength(int maneLength) {
        this.maneLength = maneLength;
    }

    @Override
    public String toString() {
        return "Lion [maneLength=" + maneLength + "]";
    }
}

class Tiger {

    private int length;

    public int getLength() {
        return length;
    }

    public void setLength(int length) {
        this.length = length;
    }

    @Override
    public String toString() {
        return "Tiger [maneLength=" + length + "]";
    }
}
String jsonLion = "{\"type\": \"LION\", \"animal\": {\"maneLength\" : 10}}";
String jsonTiger = "{\"type\": \"TIGER\", \"animal\": {\"length\" : 11}}";

ObjectMapper om = new ObjectMapper();

System.out.println(om.readValue(jsonLion, Cage.class));
System.out.println(om.readValue(jsonTiger, Cage.class));
Cage [animal=Lion [maneLength=10]]
Cage [animal=Tiger [maneLength=11]]