在没有TypeInfo的情况下向Jackson提供自定义对象实例

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在没有TypeInfo的情况下向Jackson提供自定义对象实例相关的知识,希望对你有一定的参考价值。

我正在尝试使用Jackson反序列化一些多态对象,但我不想在JSON中公开类型信息。所以,假设我们有“经典”动物情景:

public interface Animal {
    String talk();
}

public class Dog implements Animal {
    public String talk() { return "Woof!"; }
}

public class Cat implements Animal {
    public String talk() { return "Meow!"; }
}

我还有一个Factory接口和多个Factory实现:

public interface AnimalFactory {
    Animal newAnimal();
}

public class DogFactory implements AnimalFactory {
    public Animal newAnimal() { return new Dog(); }
}

public class CatFactory implements AnimalFactory {
    public Animal newAnimal() { return new Cat(); }
}

由于我不想通过在JSON中使用@JsonTypeInfotype参数来污染具有实现细节的JSON,我只知道两个选择:

  • @JsonDeserialize(as = Dog.class)上使用Animal,但这需要从API到实现类的显式依赖;而且它总是将JSON反序列化为Dog,而我只想在运行时找到合适的具体实现,因为我不知道哪个具体实现可用;
  • 使用StdDeserializer子类:
public class AnimalDeserializer extends StdDeserializer<Animal> {

    // Obtain through dependency injection or other mechanism
    private AnimalFactory animalFactory;

    public AnimalDeserializer() {
        this(null);
    }

    public AnimalDeserializer(Class<Animal> vc) {
        super(vc);
    }

    @Override
    public Animal deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        return animalFactory.newAnimal();
    }

这种方法允许我在运行时定位实现,但它也需要我手动设置和获取任何字段而不是依赖于数据绑定(当然,在这种特定情况下,这将是微不足道的,但我的对象非常复杂,我也有很多不同的接口,所以我真的需要依赖数据绑定)。

所以,我的问题是:我是否有另一种手动提供具体的Animal实例的方法,但是让杰克逊做其数据绑定魔术而不是手动实现所有这些?作为参考,如果有人有一些JAXB的经验,像@XmlRegistry这样我可以为给定的接口指定工厂将是很棒的。

谢谢!

编辑:可能不是很清楚,但我不想在JSON中放置一个type属性进行反序列化,因为我不想在那里公开实现细节,所以@JsonTypeInfo不是一个选项。

答案

您可以使用@JsonTypeInfo@JsonSubtypes进行自动多态支持。

@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.PROPERTY,
    property = "type")
@JsonSubTypes({
    @JsonSubTypes.Type(value = Cat.class, name = "cat"),
    @JsonSubTypes.Type(value = Dog.class, name = "dog")
})

public interface Animal {
    String talk();
}

以上是关于在没有TypeInfo的情况下向Jackson提供自定义对象实例的主要内容,如果未能解决你的问题,请参考以下文章

核心位置,是不是可以在没有 GPS 芯片的情况下向 iPad 提供 GPS/位置日期,以便在 CLLocationManager 类中使用?

在没有任何布局的情况下向活动添加按钮

在没有自定义单元格的情况下向 uitableview 显示详细信息披露按钮

如何在没有值的情况下向字典添加键?

如何在没有 Apple Watch 应用的情况下向 Apple Watch 发送通知

如何让用户在没有链接的情况下向他们的朋友发送私信?