java - 缺少属性 'type' 而映射的 De/Serialization 包含混合子类型 - 多态性

标签 java json jackson hashmap polymorphism

我有一个名为 的对象动物 有两个子类 Monkey 和 Lion,我使用 JsonTypeInfo 来支持子类型检测,我想在序列化 JsonTypeInfo 时应该根据类自动放置名为“type”的属性。
动物类

import java.io.Serializable;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonSubTypes({
        @JsonSubTypes.Type(value = Lion.class, name = "Lion"),
        @JsonSubTypes.Type(value = Monkey.class, name = "Monkey")
})
public class Animal implements Serializable {
    
    String name;

    public Animal(String name) {
        super();
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Animal other = (Animal) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

}

狮子类

public class Lion extends Animal{

    public Lion(String name) {
        super(name);
    }

}


猴子类

public class Monkey extends Animal{

    public Monkey(String name) {
        super(name);
    }

}

主功能
    public static void main(String[] args) throws JsonGenerationException, JsonMappingException, IOException {
        Map<String,Animal> animals = new HashMap<String, Animal>();
        animals.put("Bob", new Lion("Bob"));
        animals.put("Alice", new Monkey("Alice"));
        StringWriter sw = new StringWriter();
        ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(Include.NON_NULL);
        mapper.writeValue(sw, animals);
        String animlasStr = sw.toString();
        Map<String,Animal> dAnimalMap = mapper.readValue(animlasStr, new TypeReference<Map<String, Animal>>() {});
        assert dAnimalMap.get("Alice") instanceof Monkey;
    }
但是当我反序列化动物 map 时它不起作用!!,它抛出以下异常,类型 属性(property)丢失。
 com.fasterxml.jackson.databind.JsonMappingException: Unexpected token (END_OBJECT), expected FIELD_NAME: missing property 'type' that is to contain type id  (for class ....Animal)
 at [Source: {"Bob":{"name":"Bob"},"Alice":{"name":"Alice"}}
我尝试了类型引用和可见属性,我得到了相同的结果。
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type" , visible =true)

最佳答案

代替:mapper.writeValue(sw, animals);mapper.writerFor(new TypeReference<Map<String, ? extends Animal>>() {}).writeValue(sw, animals);而不是:mapper.readValue(animlasStr, new TypeReference<Map<String, Animal>>() {});用:mapper.readValue(animlasStr, new TypeReference<Map<String, ? extends Animal>>() {});在所有类中都有空的构造函数

关于java - 缺少属性 'type' 而映射的 De/Serialization 包含混合子类型 - 多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62615492/

相关文章:

java - 如何向 JPanel 添加缩放和平移功能?

java - 从流中读取字符串而不是字符

ruby-on-rails - 如何使用 Rails XML Builder 创建单元素 JSON 数组?

java - 用于转换 BigDecimal 值并将比例设置为 2 的 Jackson 注释

java - Jackson 方法中的只读属性

java - 您可以在JAX-RS中全局设置Jackon的Include.NON_NULL吗?

java - 有关Android优化的任何文档-JAVAC,JIT和Dalvik

java - 如何在循环链表中插入字符串(我想检查循环链表中的重复单词)?

java - Java将json字符串转换为utf 8字符串

java - 从 JSON 中获取数据不会以列表形式返回数据。进度条一直运行