Используйте JsonTypeInfo.As.EXTERNAL_PROPERTY без указания @JsonSubTypes - PullRequest
0 голосов
/ 28 декабря 2018

Можно ли использовать @JsonTypeInfo.As.EXTERNAL_PROPERTY без необходимости указывать подтипы с помощью @JsonSubtypes?

Вариант использования: я хочу создать общие базовые классы, которые имеют различные тела, которые объявленыв других проектах.

Общий базовый класс, который содержит общие поля и тело

public class ApiModel<T extends ApiBodyModel> {

    private String modelType;
    private String version;
    private T body;

... getters / setters

}

Абстрактная модель тела, которая имеет дополнительный общий контекст внутри.

@JsonTypeInfo(use = Id.NAME, include = As.EXTERNAL_PROPERTY, property = "modelType")
//@JsonTypeIdResolver(InheritanceTypeIdResolver.class)
public abstract class ApiBodyModel<T extends ApiBodyModel<T>> {

    @JsonProperty
    private ApiContextModel context;

    public T withContext(ApiContextModel context) {
        this.context = context;
        return (T) this;
    }

... getters / setters

}

Одним из решений, которое позволило мне отказаться от использования @JsonSubTypes, было использование Reflection для получения всех подтипов абстрактного ApiBodyModel, детализированного на https://gist.github.com/root-talis/36355f227ff5bb7a057ff7ad842d37a3,, нопо-прежнему требовалось, чтобы имя класса было объявлено внутри тела, а не на один уровень выше.

Примеры, найденные для использования @JsonTypeInfo.As.EXTERNAL_PROPERTY, объявили JsonSubTypes, но я хочу избежать этого, так как абстрактный класс будет вобщий проект.

1 Ответ

0 голосов
/ 09 января 2019

Я работал над этим, используя класс верхнего уровня, использующий InheritanceTypeIdResolver

Общий базовый класс, который содержит общие поля и тело

@JsonTypeInfo(use = Id.CUSTOM, property = "modelType", visible = true)
@JsonTypeIdResolver(InheritanceTypeIdResolver.class)
public abstract class ApiModel<T extends ApiBodyModel> {

    private String modelType;
    private String version;

    public abstract T getBody();

    public abstract void setBody(T body);

}

Модель абстрактного тела, которая имеет дополнительный общий контекст внутри.

public abstract class ApiBodyModel {

    private ApiContextModel context;

}

Реализация конкретного базового класса

public class ConcreteModel extends ApiModel<ConcreteBody> {

    public static final String MODEL_TYPE = "concreteModel";

    private ConcreteBody body;

    public ConcreteModel(
        String version,
        ConcreteBody body) {
        super(MODEL_TYPE, version);
        this.body = body;
    }
}

Реализация конкретного тела

public class ConcreteBody extends ApiBodyModel {

    private String source;

    public ConcreteBody(ApiContextModel context, String source) {
        super(context);
        this.source = source;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...