Десериализация Джексона Полиморфи c в указанный подтип c не удалась с "InvalidTypeIdException" - PullRequest
1 голос
/ 28 февраля 2020

У меня есть полиморфный тип данных c, который я пытаюсь десериализовать непосредственно в его подтип (для обратной совместимости), но без информации о типе я не могу десериализовать, даже если я непосредственно ссылаюсь на подтип в readValue вызов объекта сопоставления. Есть ли какие-нибудь волхвы Джексона c, которые я могу использовать, чтобы исправить это?

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'

В настоящее время я использую Джексона 2.9.8

1 Ответ

0 голосов
/ 02 марта 2020

Вы можете использовать JsonTypeInfo.Id.NONE, если вы можете указать конкретный класс в objectmapper.readValue.

. Для полноты javado c из NONE:

Это означает, что никакие метаданные явного типа не включены, и ввод текста производится чисто с использованием контекстной информации, возможно, дополненной другими аннотациями.

Вот тестовый пример 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;
    }
}
...