当前位置: 首页 > 知识库问答 >
问题:

对包含混合子类型多态性的映射进行反序列化/序列化时,缺少属性“type”

年健
2023-03-14

我有一个名为Animal的对象,有两个子类,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;
    }

但当我反序列化动物地图时,它就不起作用了!!,它引发以下异常,类型属性缺失。

 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)

共有1个答案

昝唯
2023-03-14

而不是:mapper.writeValue(sw,动物);使用mapper.writerFor(new Type参考

而不是:mapper.readValue(AnimlasStr,新的Type参考

所有类中都有空构造函数

 类似资料:
  • 我的JSON字符串是: 我想要实现的是,当JSON中没有提供schemaVersion时,能够在默认情况下反序列化到SubClassV1,但即使在Superclass中将schemaVersion初始化为“1.0”时,我仍然会收到以下错误:

  • 我想反序列化以下XML(缩短示例): 到目前为止,我想出的代码: 但这种方法存在几个问题: > @JacksonXmlProperty t(localName="subject")始终为空,因为我将其用于类型信息。为什么?,或者如何绕过它? 还是这种方法已经错了? 最后是我使用的周围类:

  • 问题内容: 我如何才能序列化一个特定的属性,但又防止其反序列化回POCO?是否可以使用属性装饰特定属性? 基本上,我正在寻找一个与ShouldSerialize *方法等效的反序列化方法。 我知道我可以编写一个自定义转换器,但是这样做似乎有点过头了。 编辑: 这里还有一些背景。这背后的原因是我的课看起来像: 我需要请求的属性,但是我不希望它反序列化并触发设置程序逻辑。 问题答案: 最简单的方法是将

  • 问题内容: 我有一个简单的接口与属性的getter和setter。 我还有另一个实现此接口的UserAccount类。 我的问题是我想序列化money属性,但在反序列化它时忽略它,即,不接受用户对此属性的任何值。我在setter上尝试过@JsonIgnore,在getter上尝试过@JsonIgnore(false),它确实会忽略它,但是在序列化它时也会这样做。 我在setter上尝试了@Json

  • 我有另一个类UserAccount实现了这个接口。 我的问题是,我想序列化money属性,但在反序列化时忽略它,即不接受用户对该属性的任何值。我在setter上尝试了@jsonIgnore,在getter上尝试了@jsonIgnore(false),它确实忽略了它,但是它在序列化它的同时也忽略了它。 我在setter上尝试了@jsonIgnore,在getter上尝试了@jsonProperty,

  • 可以序列化/反序列化< code >映射吗 在这种特殊情况下,我知道总是,和 - 第三方类(我有序列化器和反序列化器),其他值是盒装原语。 有可能和杰克逊做这样的事吗?使用MapSerializer/MapDeserializer可以做到这一点吗?(我找不到任何例子)