Полиморфная десериализация в Джексоне на основе целых чисел, а не строк

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

@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.PROPERTY,
    property = "methodName")
@JsonSubTypes({
    @JsonSubTypes.Type(value = MyFirstClass.class, name = "firstClassName"),
    @JsonSubTypes.Type(value = MySecondClass.class, name = "secondClassName")}) 

Я не могу найти простого примера того, как это сделать, если значение является целым числом, а не строкой. Например, как мне выбрать класс для десериализации, если вместо «methodName»: «firstClassName» мой JSON включает «methodName»: 1?


person secureboot    schedule 31.07.2013    source источник


Ответы (2)


Не существует «простого» способа сделать это. Вы должны написать свою собственную реализацию механизма сериализации и одну для десериализации. Опасностей такой реализации так много, что вам лучше просто указать свое свойство typeinfo в кавычках и использовать его как строку.

person Nikola Yovchev    schedule 31.07.2013

Если вас интересует только десериализация, вы можете установить значение элемента name элемента @JsonSubTypes.Type в строковое представление целого числа. Это правильно десериализует числовое значение в JSON. Однако при сериализации оно будет сериализовано в строковое представление этого значения, а не в число (например, "1" вместо 1).

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "methodName")
@JsonSubTypes({
        @JsonSubTypes.Type(value = MyFirstClass.class, name = "1"),
        @JsonSubTypes.Type(value = MySecondClass.class, name = "2")})

В качестве альтернативы вы можете сериализовать и десериализовать его в число вместо строки с немного большим количеством шаблонного кода, если вы хотите добавить метод для этого значения, дублирующий объявления значений из @JsonSubTypes.Type:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "methodName", include = JsonTypeInfo.As.EXISTING_PROPERTY)
@JsonSubTypes({
        @JsonSubTypes.Type(value = MyFirstClass.class, name = "1"),
        @JsonSubTypes.Type(value = MySecondClass.class, name = "2")})
public static abstract class Superclass {
    public abstract int getMethodName();
}

public static class MyFirstClass extends Superclass {
    @Override
    public int getMethodName() {
        return 1;
    }
}

public static class MySecondClass extends Superclass {
    @Override
    public int getMethodName() {
        return 2;
    }
}
person M. Justin    schedule 26.06.2019