我正在尝试使用 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
删除,则可以正常反序列化。所以这让我认为问题出在子类型解决中,但不确定出了什么问题,有什么想法吗?
我发现问题了,你应该将
@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))