【问题标题】:Overriding @JsonTypeInfo not working when using it for class field like List<Animal> where Animal is annotated with it将 @JsonTypeInfo 用于 List<Animal> 等类字段时,覆盖 @JsonTypeInfo 不起作用,其中 Animal 被注释
【发布时间】:2012-08-29 20:38:21
【问题描述】:

朋友们,

我在特定场景中覆盖 @JsonTypeInfo 注释时遇到问题。

请在下面找到我的班级结构。

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY,    
property = "@type")
class Animal {
    public String name = "animalName";

    /**
     * @return the name
     */ 
    public String getName() {
   return name;
    }

    /**
     * @param name
     *            the name to set
     */

    public void setName(String name) {
    this.name = name;
    }

}

class Cat extends Animal {
boolean likesCream = true;
public int lives = 10;

/*
 * (non-Javadoc)
 * 
 * @see java.lang.Object#toString()
 */
@Override
public String toString() {
return "Cat [likesCream=" + likesCream + ", lives=" + lives + ", name="
    + name + "]";
}

/**
 * @return the likesCream
 */
public boolean isLikesCream() {
return likesCream;
}

/**
 * @param likesCream
 *            the likesCream to set
 */
public void setLikesCream(boolean likesCream) {
this.likesCream = likesCream;
}

/**
 * @return the lives
 */
public int getLives() {
return lives;
}

/**
 * @param lives
 *            the lives to set
 */
public void setLives(int lives) {
this.lives = lives;
}

}

class Dog extends Animal {
public double barkVolume; // in decibels

/*
 * (non-Javadoc)
 * 
 * @see java.lang.Object#toString()
 */
@Override
public String toString() {
return "Dog [barkVolume=" + barkVolume + ", name=" + name + "]";
}

/**
 * @return the barkVolume
 */
public double getBarkVolume() {
return barkVolume;
}

/**
 * @param barkVolume
 *            the barkVolume to set
 */
public void setBarkVolume(double barkVolume) {
this.barkVolume = barkVolume;
}

}

现在我在需要序列化/反序列化的 Zoo 类中使用上述类。

class Zoo2i {

    List<Animal> animals;

    Dog dog;

    /**
     * @return the animals
     */
    public List<Animal> getAnimals() {
    return animals;
    }

    /**
     * @param animals
     *            the animals to set
     */
    @JsonTypeInfo(use = JsonTypeInfo.Id.NONE, include = JsonTypeInfo.As.PROPERTY,    
                 property = "@type")
   public void setAnimals(List<Animal> animals) {
   this.animals = animals;
   }

    /**
     * @return the dog
     */
    public Dog getDog() {
    return dog;
    }

    /**
     * @param dog
     *            the dog to set
     */
    @JsonTypeInfo(use = JsonTypeInfo.Id.NONE, include = JsonTypeInfo.As.PROPERTY,    
                  property = "@type")
     public void setDog(Dog dog) {
    this.dog = dog;
    }
}

因为我已经注解了 Animal 类,它会默认将类型信息添加到它的所有子类中以支持多态性。

列表可以有所有类型,例如动物、狗、猫。 我的要求是我不希望 List 中 Animal 实例本身的类型信息以及 zoo2i 类中 Dog 类型的其他属性的类型信息。

我成功地覆盖了 setDog(....) 的注释,但失败了 setAnimals(...)(请参阅 Zoo2i 类)。

是否有任何不同的方法可以排除带注释的类本身的类型信息或在反序列化期间使类型信息可选(非强制性)。

还有一件事,默认情况下,使用 Animal 及其所有实例,类型信息包含在 Animal 注释中,我希望只有当我直接使用 Cat 时才包含 Dog 然后类型信息不应该被包含并且不应该被期望在反序列化期间;

【问题讨论】:

    标签: json jackson


    【解决方案1】:

    我不认为这是一个受支持的用例:您应该在要使用的基本类型上使用@JsonTypeInfo,或者在属性上使用(对于未注释的类型)。不要尝试混合方法。一个类型是否应该包含类型信息——在某些情况下尝试以一种方式来做,而在其他情况下尝试另一种方式听起来像是一种危险的微优化。

    【讨论】:

    • 是的,但我需要实现这一点。我只希望当 Animal Animal = Animal 时,意味着当值和声明字段都属于同一类型时,不应在序列化/反序列化中考虑类型信息,对于多态和任何其他类型,应该是。
    • 好的,那祝你好运! FWIW,反序列化可以成功,只要您将“defaultImpl”定义为基类本身。
    • 是的,我也想知道。但我不知道如何使用 @JsonTypeInfo 注释的 defaultImpl 来处理反序列化期间不存在类型信息的情况。我应该在那个类中创建什么方法.....请找到我的注释用法。 @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class" ,defaultImpl = DefaultImpl.class) 我应该在 DefaultImpl 类中写什么
    • 什么都没有。如果类型信息不匹配,则使用默认 impl 类的实例,就像 id 匹配一样。就像任何其他比赛一样。所以你写 DefaultImpl 就像任何其他 Animal 类型一样。默认情况下,Jackson 处理类型 id 的所有详细信息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-20
    • 1970-01-01
    • 2014-05-03
    • 1970-01-01
    相关资源
    最近更新 更多