反序列化 JSON 数组,包括类型信息

问题描述 投票:0回答:1

我正在尝试使用 Jackson 反序列化 JSON 数组,其中第一个元素是类型 ID,然后还有一些其他元素,最后是第一个元素指定的类型的有效负载。尝试解析类型似乎失败

我在这里做了一个简化的可运行示例

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.ObjectMapper;

class Scratch {

    private static  ObjectMapper objectMapper = new ObjectMapper();

    @JsonFormat(shape = JsonFormat.Shape.ARRAY)
    @JsonPropertyOrder({"type", "uniqueId", "animal"})
    public static class Wrapper {

        public String type;
        public String uniqueId;

        @JsonTypeInfo(
                use = JsonTypeInfo.Id.NAME,
                include = JsonTypeInfo.As.EXTERNAL_PROPERTY,
                property = "type"
        )
        @JsonSubTypes({
                @JsonSubTypes.Type(value = Cat.class, name = "cat")
        })
        public Animal animal;
    }

    public interface Animal {
        int getLegs();
    }

    public static class Cat implements Animal {

        public int legs = 4;
        @Override
        public int getLegs() {
            return legs;
        }
    }

    public static void main(String[] args) throws Exception {
        Wrapper wrapper = new Wrapper();
        wrapper.type = "cat";
        wrapper.uniqueId = "123";
        wrapper.animal = new Cat();

        String json = objectMapper.writeValueAsString(wrapper);
        System.out.println(json);

        Wrapper deserialized = objectMapper.readValue(json, Wrapper.class);
        System.out.println(deserialized);
    }
}

可以正确序列化为

["cat","123",{"legs":4}]

但是当尝试反序列化时会抛出异常。

Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `Scratch$Wrapper` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (String)"["cat","123",{"legs":4}]"; line: 1, column: 1]
    at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
    at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1728)
    at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1353)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1415)
    at com.fasterxml.jackson.databind.deser.impl.BeanAsArrayDeserializer._deserializeNonVanilla(BeanAsArrayDeserializer.java:226)
    at com.fasterxml.jackson.databind.deser.impl.BeanAsArrayDeserializer.deserialize(BeanAsArrayDeserializer.java:108)
    at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:323)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4674)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3629)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3597)
    at Scratch.main(scratch_86.java:51)

如果

Wrapper
中的字段类型从
Animal
更改为
Cat
并且将
@JsonTypeInfo
@JsonSubTypes
删除,则可以正常反序列化。所以这让我认为问题出在子类型解决中,但不确定出了什么问题,有什么想法吗?

java arrays json jackson
1个回答
0
投票

我发现问题了,你应该将

@JsonFormat(shape = JsonFormat.Shape.ARRAY)
更改为
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
@JsonFormat(shape = JsonFormat.Shape.ANY)
或者你也可以删除它。

输出

{"type":"cat","uniqueId":"123","animal":{"legs":4}}
Scratch.Wrapper(type=cat, uniqueId=123, animal=Scratch.Cat(legs=4))
© www.soinside.com 2019 - 2024. All rights reserved.