Java Jackson多态反序列化到特定子类型失败,带“0”;InvalidTypeIdeException“;
我有一个多态数据类型,我正试图直接反序列化到它的子类型中(为了向后兼容),但是没有类型信息,我无法反序列化,即使我在对象映射器上的Java Jackson多态反序列化到特定子类型失败,带“0”;InvalidTypeIdeException“;,java,kotlin,jackson,polymorphism,Java,Kotlin,Jackson,Polymorphism,我有一个多态数据类型,我正试图直接反序列化到它的子类型中(为了向后兼容),但是没有类型信息,我无法反序列化,即使我在对象映射器上的readValue调用中直接引用子类型。我可以用杰克逊的魔法来解决这个问题吗 class SerializationTest { @Test fun serializationTest() { val serializedFoo = """ {"base":"blah", "foo": "something"} """
readValue
调用中直接引用子类型。我可以用杰克逊的魔法来解决这个问题吗
class SerializationTest {
@Test
fun serializationTest() {
val serializedFoo = """ {"base":"blah", "foo": "something"} """
val foo = ObjectMapper().registerModule(KotlinModule()).readValue(serializedFoo, Foo::class.java)
println(foo)
}
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
@JsonSubTypes(
JsonSubTypes.Type(value = Foo::class),
JsonSubTypes.Type(value = Bar::class)
)
internal abstract class Base {
abstract val base: String
}
internal class Foo(@JsonProperty("base") override val base: String,
@JsonProperty("foo") val foo: String): Base()
internal class Bar(@JsonProperty("base") override val base: String,
@JsonProperty("foo") val bar: String): Base()
}
失败于
com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Missing type id when trying to resolve subtype of [simple type, class com.foo.bar.SerializationTest$Foo]: missing type id property '@class'
我目前正在使用jackson 2.9.8如果可以在
objectmapper.readValue
中指定具体类,那么可以使用JsonTypeInfo.Id.NONE
为完整起见,来自NONE
的javadoc:
这意味着不包括显式的类型元数据,而且键入操作完全是使用上下文信息完成的,可能还添加了其他注释
下面是一个Java测试用例:
public class SerializationTest {
@Test
public void serializationTest() throws JsonParseException, JsonMappingException, IOException {
final String json = getSerializedFoo();
final ObjectMapper om = getObjectMapper();
final Foo value = om.readValue(json, Foo.class);
assertTrue(value != null);
}
private ObjectMapper getObjectMapper() {
final ObjectMapper om = new ObjectMapper();
return om;
}
private String getSerializedFoo() {
return "{\"base\": \"blah\", \"foo\": \"something\"}";
}
}
@JsonTypeInfo(use = JsonTypeInfo.Id.NONE)
@JsonSubTypes({
@Type(value = Foo.class),
@Type(value = Bar.class)
})
abstract class Base {
@JsonProperty("base")
protected String base;
public String getBase() {
return base;
}
public void setBase(final String base) {
this.base = base;
}
}
class Bar extends Base {
@JsonProperty("bar")
private String bar;
public String getBar() {
return bar;
}
public void setBar(final String foo) {
bar = foo;
}
}
class Foo extends Base {
@JsonProperty("foo")
private String foo;
public String getFoo() {
return foo;
}
public void setFoo(final String foo) {
this.foo = foo;
}
}
如果可以在
objectmapper.readValue
中指定具体类,则可以使用JsonTypeInfo.Id.NONE
为完整起见,来自NONE
的javadoc:
这意味着不包括显式的类型元数据,而且键入操作完全是使用上下文信息完成的,可能还添加了其他注释
下面是一个Java测试用例:
public class SerializationTest {
@Test
public void serializationTest() throws JsonParseException, JsonMappingException, IOException {
final String json = getSerializedFoo();
final ObjectMapper om = getObjectMapper();
final Foo value = om.readValue(json, Foo.class);
assertTrue(value != null);
}
private ObjectMapper getObjectMapper() {
final ObjectMapper om = new ObjectMapper();
return om;
}
private String getSerializedFoo() {
return "{\"base\": \"blah\", \"foo\": \"something\"}";
}
}
@JsonTypeInfo(use = JsonTypeInfo.Id.NONE)
@JsonSubTypes({
@Type(value = Foo.class),
@Type(value = Bar.class)
})
abstract class Base {
@JsonProperty("base")
protected String base;
public String getBase() {
return base;
}
public void setBase(final String base) {
this.base = base;
}
}
class Bar extends Base {
@JsonProperty("bar")
private String bar;
public String getBar() {
return bar;
}
public void setBar(final String foo) {
bar = foo;
}
}
class Foo extends Base {
@JsonProperty("foo")
private String foo;
public String getFoo() {
return foo;
}
public void setFoo(final String foo) {
this.foo = foo;
}
}
您的json字符串
serializedFoo
不完整,它应该定义了“@class”
字段。如果您不能更改json字符串或使用自定义反序列化程序,可能需要查看JsonTypeInfo.Id.NONE
。我目前基本上是想摆脱自定义反序列化程序,但要以向后兼容的方式进行。有一个队列正在写入/读取这些消息,因此我需要一种方法来展开我的更改,理想情况下,不破坏队列中已有消息的反序列化。如果我将其读入Base
中,我知道为什么需要类型信息,但是由于我显式地给它要反序列化的类型,我如何使它避免需要该类型?您的json字符串serializedFoo
不完整,它应该定义字段“@class”
。如果您不能更改json字符串或使用自定义反序列化程序,可能需要查看JsonTypeInfo.Id.NONE
。我目前基本上是想摆脱自定义反序列化程序,但要以向后兼容的方式进行。有一个队列正在写入/读取这些消息,因此我需要一种方法来展开我的更改,理想情况下,不破坏队列中已有消息的反序列化。如果我把它读入Base
中,我会明白为什么需要类型信息,但是既然我显式地给了它要反序列化的类型,我如何使它避免需要类型?