不使用注释的杰克逊多态反序列化 [英] Jackson polymorphic deserialisation without using annotations

查看:145
本文介绍了不使用注释的杰克逊多态反序列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Animal类,它接受通用类型参数T,如下所示:

I have an Animal class accepting a generic type parameter T, as shown below:

public class Animal<T> {
    private String type;
    private T details;

    // getters and setters
}

type参数可以是DogCat.

The type parameter can be Dog or Cat.

public class Dog {
    private String name;
    private boolean goodBoy;

    // no-arg, all-args constructors, getters and setters
}

public class Cat {
    private String name;
    private boolean naughty;

    // no-arg, all-args constructors, getters and setters
}

我正在尝试反序列化以下JSON.

I am trying to deserialise the following JSON.

{
    "type": "dog",
    "details": {
        "name": "Marley",
        "goodBoy": true
    }
}

但是,当我反序列化时,字段详细信息总是反序列化为LinkedHashMap而不是类的特定实现.

However, when I deserialise, the field details always gets deserialised as a LinkedHashMap and not the particular implementation of the class.

public static void main(String[] args) throws IOException {
    ObjectMapper mapper = new ObjectMapper();

    Animal<Dog> dog = new Animal<>();
    dog.setType("dog");
    dog.setDetails(new Dog("Marley", true));

    String dogJson = mapper.writeValueAsString(dog);
    Animal dogDeserialized = mapper.readValue(dogJson, Animal.class);

    // dogDeserialized's details is LinkedHashMap
}

我不能更改上述类,因此不能在字段上使用注释.有没有一种方法可以指定ObjectMapper可以将details字段反序列化的类的列表?

I cannot change the above classes, and so can't use annotations on the field. Is there a way I can specify the list of classes which the ObjectMapper may deserialise the details field to ?

请注意,对于各个DogCat类,type字段的值设置为"dog"或"cat".

Note that the value of the type field is set to "dog" or "cat" for respective Dog or Cat classes.

推荐答案

使用TypeReference指定要反序列化的类型

Use TypeReference to specify the type to Deserialized

Animal<Dog> dogDeserialized = mapper.readValue(
    dogJson, new TypeReference<Animal<Dog>>() {});

或者代替DogCat,您只能拥有一个具有所有属性的类

Or instead of Dog and Cat you can have only one class with all the properties

public class AnimalDetails {

  private String name;
  private Boolean goodBoy;
  private Boolean naughty;

 }

并设置ObjectMapper以忽略JSON中的未知属性:

And set ObjectMapper to ignore unknown properties in the JSON:

 ObjectMapper mapper = new ObjectMapper()
  .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

因此,如果它是Dog类,则naughty将是null,如果它是Cat类,则goodBoy将是null

So if it is Dog class naughty will be null and if it is Cat class goodBoy will be null

这篇关于不使用注释的杰克逊多态反序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆