Java универсальный объект ответа клиента jax-rs - PullRequest
2 голосов
/ 06 марта 2020

У меня проблема с универсальной c функцией. Я хочу использовать функцию, которой я назначаю определенный класс / тип, чтобы сначала сгенерировать соответствующий результат из ответа покоя, а затем вернуть его.

public class TimerService {

    [...]

    public <T extends myObjInterface> RestMessageContainer<T> send(String endpointPath, Map<String, String> parameters, Class<T> clazz) {
        [...]
        Response response = webTarget.request(MediaType.APPLICATION_JSON_TYPE).get();
        RestMessageContainer<T> container = response.readEntity(new GenericType<RestMessageContainer<T>>() {});
        return container;
    }
}

public class RestMessageContainer<T extends myObjInterface> {

    [...]

    @XmlAttribute(name = "data")
    private List<T> data;

    [...]
}

Я получаю следующее сообщение об ошибке во время выполнения.

Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct     instance of `com.test.myObjInterface` (no Creators, like default construct, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
14:47:41,982 ERROR [stderr] (EJB default - 2)  at [Source: (org.jboss.resteasy.client.jaxrs.internal.ClientResponse$InputStreamWrapper); line: 3, column: 14] (through reference chain: com.test.RestMessageContainer["data"]->java.util.ArrayList[0])

Выводится ошибка для строки RestMessageContainer<T> container = response.readEntity(new GenericType<RestMessageContainer<T>>() {});

Правильно ли подходит мой подход или как мне решить мою проблему?

Ответы [ 2 ]

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

Спасибо за ваш совет, у меня есть несколько подклассов. Информация о типе в строках JSON отсутствует. Тип является результатом адреса запроса. Я не мог настроить Джексона для распознавания подтипа. В строках JSON нет уникального поля, которое я мог бы использовать как тип. Я не могу изменить веб-сервис, который доставляет строки JSON.


[ОБНОВЛЕНИЕ]

Я нашел решение. Я больше не позволяю клиенту JAX-RS преобразовывать строку JSON. У меня есть строка JSON, возвращенная мне как строка, и я независимо конвертирую ее, используя Джексона.

    public <T extends myObjInterface> RestMessageContainer<T> send(String endpointPath, Map<String, String> parameters, Class<T> clazz) {
        [...]
        Response response = webTarget.request(MediaType.APPLICATION_JSON_TYPE).get();

        ObjectMapper mapper = new ObjectMapper();
        mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
        mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

        RestMessageContainer<T> container = mapper.readValue(response.readEntity(String.class), mapper.getTypeFactory().constructParametricType(RestMessageContainer.class, clazz));

        return container;
    }
0 голосов
/ 06 марта 2020

Вы не можете создать экземпляр абстрактного класса. Однако вы можете решить проблему с помощью простой аннотации - @JsonDeserialize для абстрактного класса:

@JsonDeserialize(as = Cat.class)
abstract class Animal {...}

В вашем случае абстрактный класс будет myObjInterface.

Примечание: Если у вас есть более одного подтипа абстрактного класса, вам следует рассмотреть возможность включения информации о подтипе, как показано в этом посте .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...