#java #json #jackson #retrofit #jackson-databind
#java #json #джексон #модернизация #джексон-привязка данных
Вопрос:
У меня есть объект ответа, который всегда включает объект ответа как свойство и различные типы значений, поэтому у меня есть интерфейс в классе как поле, чтобы он обеспечивал правильную реализацию на основе некоторого уникального идентификатора значения.
Could not execute the callcom.fasterxml.jackson.databind.exc.InvalidTypeIdException: Missing type id when trying to resolve subtype of [simple type, class com.opngo.nowos.nowos.api.response.DataResponse]: missing type id property 'operation' (for POJO property 'response')
at [Source: (okhttp3.ResponseBody$BomAwareReader); line: 1, column: 180] (through reference chain: com.opngo.nowos.nowos.NowOSResponse["response"])
Вот мой интерфейс
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "operation")
@JsonSubTypes({@JsonSubTypes.Type(value = AuthResponse.class, name = "account_auth")})
public interface IResponse {
///
}
Вот один из объектов ответа, который реализует интерфейс, упомянутый выше
@RequiredArgsConstructor
public class AuthResponse implements IResponse {
@JsonProperty
private final String accountID;
@JsonProperty
private final String authToken;
@JsonProperty
private final String language;
}
Вот основной ответ, который имеет этот интерфейс, который должен привести к правильному объекту ответа
public class NowOSResponse {
@JsonProperty
private final String operation;
@JsonProperty
private final String version;
@JsonProperty
private final IResponse response;
@JsonProperty
private final String status;
}
Похоже, что он не просматривает родительский элемент и ищет поле operation в authResponse, которое, конечно, пустое, поскольку поле operation всегда присутствует в родительском элементе, и у этого родительского элемента есть response -> authResponse -> CreateAccResponse и так далее
Ответ №1:
я хотел бы опубликовать решение, которое, надеюсь, поможет вам.
Если у вас есть объект внутри объекта, который всегда возвращает разные свойства, вы можете использовать следующее :
1) Создайте абстрактный класс, например MainResponse, этот ответ будет содержать статус и операцию, поскольку эти свойства являются постоянными
public abstract class MainResponse {
@JsonProperty
private String version;
public abstract IResponse getResponse(); // so we declaring it abstract so that all the childrens have to override it in order to return specific interface realisation
}
Теперь нам нужно создать конкретное тело ответа, которое должно быть возвращено на основе вызова api.
@Getter
@JsonIgnoreProperties(ignoreUnknown = true)
public class AuthResponse implements IResponse {
@JsonProperty
private String accountID;
@JsonProperty
private String authToken;
}
Теперь, поскольку json будет ожидать свойство response json, мы должны создать дополнительный класс, который расширит абстрактный класс, что означает, что у нас будет GetResponse, которому требуется IResponse в качестве возврата, и, следовательно, мы должны реализовать этот интерфейс в authResponse , мы можем просто заключить authResponse как объект композиции в новом, скажем, классе NewResponse иверните его.
@Getter
public class NewResponse extends MainResponse {
@JsonProperty
private AuthResponse response;
}