【问题标题】:Deserialize a list of objects with Jackson使用 Jackson 反序列化对象列表
【发布时间】:2022-01-22 22:49:52
【问题描述】:

我有一个对象列表,每个对象都有指定的字段(变量类型),所以我想我将创建一个主类(超类),其中包含共享元素(变量)和特定类型变量的两个子类. 我想将所有子类反序列化为超类的类型,以便我可以将所有这些 Json 放入相同对象的列表中。

这是我的 Json 示例

[ { "query": "age", "type": "numeric", "min": 5, "max": 99 }, {“查询”:“诊断”,“类型”:“字符串”,“输入”:[“husten”, "schnupfen"] } ]

我写的反序列化代码是:

public class Query{
    private String query;
    private String type;
    // Getters and Setters and constructor
}

public class QueryString extends Query implements Serializable {
    private List<String> in;
    private String like;
    // Getters and Setters and constructor
}

public class QueryNum extends Field implements Serializable {
    private Number min;
    private Number max;
    // Getters and Setters and constructor
}

使用 ObjectMapper 的序列化按预期工作,但是编译器通过反序列化给我一个无法识别的值(这是我的子类的字段)。

我想得到一个对象列表(查询) 包含 QueryString 和 QueryNum 的列表。

Java 中的 Jackson Json 有可能吗?

对于我使用的反序列化:

    ObjectMapper mapper = new ObjectMapper();

    List<Query> queries= Arrays.asList(mapper.readValue(JsonString, Query[].class));

提前致谢

【问题讨论】:

    标签: java json serialization jackson deserialization


    【解决方案1】:

    如果您在每个对象中有一个字段可用于识别要构建的对象,则可以使用注解@JsonTypeInfo

    注释用于配置类型信息是否以及如何与 JSON 序列化和反序列化一起使用的详细信息,以保留有关 Object 实例的实际类的信息。这对于多态类型是必要的,也可能需要链接抽象声明的类型和匹配的具体实现。

    @JsonSubTypes:

    与 JsonTypeInfo 一起使用的注解指示可序列化多态类型的子类型,并关联 JSON 内容中使用的逻辑名称(这比使用物理 Java 类名称更便携)。

    或者JsonTypeName:

    注解用于绑定被注解的类所具有的逻辑名。与 JsonTypeInfo(特别是其 JsonTypeInfo.use() 属性)一起使用,以建立类型名称和类型之间的关系。

    基本上,您需要在@JsonTypeInfo 中定义一个包含与要实例化的类相关信息的属性,并在@JsonSubTypes 中定义可能的值

    这是一个例子

    @JsonTypeInfo(
      use = JsonTypeInfo.Id.NAME, 
      include = As.PROPERTY, 
      property = "type")
    @JsonSubTypes({
        @JsonSubTypes.Type(value = Dog.class, name = "dog"),
        @JsonSubTypes.Type(value = Cat.class, name = "cat")
    })
    public class Animal {
        // The property type is used to know what object instantiate
        private String type;
        ...
    }
    
    @JsonTypeName("dog")
    public class Dog extends Animal {
        ...
    }
    
    @JsonTypeName("cat")
    public class Cat extends Animal {
        ...
    }
    

    如果您没有此类字段,则需要创建自定义反序列化器。

    另一种方法是将您的记录转换为Map 的列表,因为Map 可以包含任何有效对象。

    【讨论】:

    • 非常感谢。它奏效了。
    • 我现在唯一遇到的问题是“type”的值总是反序列化为 null 而不是实际值(在您的示例中为“dog”和“cat”)。
    • 我刚刚添加了@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = As.PROPERTY, property = "type", visible=true),它现在按预期工作
    猜你喜欢
    • 2020-08-07
    • 2019-10-25
    • 2014-03-11
    • 2014-02-12
    • 2023-03-13
    • 1970-01-01
    • 2018-12-26
    • 2018-05-09
    • 1970-01-01
    相关资源
    最近更新 更多