Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Jackson多态反序列化到特定子类型失败,带“0”;InvalidTypeIdeException“;_Java_Kotlin_Jackson_Polymorphism - Fatal编程技术网

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
中,我会明白为什么需要类型信息,但是既然我显式地给了它要反序列化的类型,我如何使它避免需要类型?