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

我有一些这样的课程:

@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")
public abstract class Cage<ANIMAL> {

  private AnimalType type;
  private ANIMAL animal;

}

public enum AnimalType {

    LION, TIGER

}

public LionCage extends Cage<Lion>{

    public LionCage(){
        super(AnimalType.LION);
    }
}

public Lion {

 private int maneLength;

}

public class Zoo {

   private List<Cage<?>> cages = new LinkedList<Cage<?>>();

}

现在,如果我尝试执行以下操作:

String json = "{cages: [{\"type\": \"LION\", \"animal\": {\"maneLength\" : 10}}]}";

ObjectMapper om = new ObjectMapper();

Cage cage = om.readValue(json, Zoo.class);

网箱中的第一个值应该是LionCage类型,它是.

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

我正在使用杰克逊1.

谢谢!

最佳答案
对于List问题,这是您想要使用原始类型的一次.将Cage类型参数声明为raw,而不是使用通配符进行参数化.

public class Zoo {

    private List<Cage> cages = new LinkedList<Cage>();
    // ... getters and setters similarly
}

使用通配符,您告诉Jackson它没关系,所以它使用默认的LinkedHashMap.如果删除通配符并使用原始类型,则需要在其他位置查找提示.在这种情况下,它将查看它使用的实际Cage实现.

你的JSON应该是这样的

String json = "{\"type\": \"LION\", \"animal\": {\"maneLength\" : 10}}";

杰克逊将能够确定该动物是狮子.

通过该类型,它将知道它是一个LionCage并通过类的定义

public LionCage extends Cage<Lion>{

它会知道对类型变量Animal的任何引用实际上都应该是Lion.

我在杰克逊2号.

但它也适用于Jackson 1.代码如下

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.annotate.JsonSubTypes;
import org.codehaus.jackson.annotate.JsonTypeInfo;
import org.codehaus.jackson.map.ObjectMapper;

public class Example {

    public static void main(String[] args) throws Exception {
        String json = "{\"type\": \"LION\", \"animal\": {\"maneLength\" : 10}}";

        ObjectMapper om = new ObjectMapper();

        Cage cage = om.readValue(json, Cage.class);
        System.out.println(cage.getClass());
        System.out.println(cage.getAnimal());

        System.out.println(((Lion) cage.getAnimal()).getManeLength());
    }
}

class Lion {

    private int maneLength;

    public int getManeLength() {
        return maneLength;
    }

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

class LionCage extends Cage<Lion> {

    public LionCage() {
        super(AnimalType.LION);
    }
}

class Tiger {
}

class TigerCage extends Cage<Tiger> {

    public TigerCage() {
        super(AnimalType.TIGER);
    }
}

@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")
abstract class Cage<Animal> {

    public Cage(AnimalType type) {
        this.setType(type);
    }

    public AnimalType getType() {
        return type;
    }

    public void setType(AnimalType type) {
        this.type = type;
    }

    public Animal getAnimal() {
        return animal;
    }

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

    private AnimalType type;
    private Animal animal;
}

enum AnimalType {
    LION, TIGER;
}

版画

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

转载注明原文:如何使用Jackson反序列化泛型类? - 代码日志