Подтвердить что ты не робот

Дженерики с Spring RESTTemplate

У меня такой класс:

public class Wrapper<T> {

 private String message;
 private T data;

 public String getMessage() {
    return message;
 }

 public void setMessage(String message) {
    this.message = message;
 }

 public T getData() {
    return data;
 }

 public void setData(T data) {
    this.data = data;
 }

}

и я использую resttemplate следующим образом:

...
Wrapper<Model> response = restTemplate.getForObject(URL, Wrapper.class, myMap);
Model model = response.getData();
...

Однако он бросает:

ClassCastException

Я читал это: Проблема при попытке использовать Джексона в java, но не помогла. Есть несколько тем, связанных с моей проблемой и т. Д.: https://jira.springsource.org/browse/SPR-7002 и https://jira.springsource.org/browse/SPR-7023

Есть идеи?

PS: Моя ошибка такова:

java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to a.b.c.d.Model

Я думаю, resttemplate не может понять мою общую переменную и, возможно, она принимает ее как объект вместо общего T. Таким образом, он становится LinkedHashMap. Вы можете прочитать это здесь. Здесь говорится, что, объясняя, из чего он идет:

JSON Type | Тип Java

объект | LinkedHashMap

4b9b3361

Ответ 1

ParameterizedTypeReference была введена в 3.2 M2 для решения этой проблемы.

Wrapper<Model> response = restClient.exchange(loginUrl, 
                          HttpMethod.GET, 
                          null, 
                          new ParameterizedTypeReference<Wrapper<Model>>() {}).getBody();

Однако вариант postForObject/getForObject не был введен.

Ответ 2

Единственное, что, я думаю, вы можете сделать, это создать новый класс, который расширяет Wrapper и использует модель как общий.

class WrapperWithModel extends Wrapper<Model>{};

WrapperWithModel response = restTemplate.getForObject(URL, WrapperWithModel.class);

Это не лучшее решение, но по крайней мере вам не придется вручную отменить ответ.

Ответ 3

Не используйте generics с RestTemplate. Оберните запрос и объект ответа с объектом-оболочкой, который скроет дженерики.

Ответ 4

Для этого вам не нужна даже обертка. Попробуйте это.

/**
 * 
 * Method for GET Operations
 * 
 * @param url url to send request
 * @return returned json String
 * @throws Exception exception thrown
 */
public List<T> getJSONString(String url, Class<T[]> clazz) throws Exception {

    logger.debug("getJSONString() : Start");

    List<T> response = null;

    ResponseEntity<T[]> responseEntity = null;

    List<String> hostList = Arrays.asList(propertyFileReader.getRestApiHostList().split("\\s*,\\s*"));

    Iterator<String> hostListIter = hostList.iterator();

    String host = null;

    while (true) {
        try {
            host = hostListIter.next();

            logger.debug("getJSONString() : url={}", (host + url));
            responseEntity = restTemplate.getForEntity(host + url, clazz);
            if (responseEntity != null) {
                response = Arrays.asList(responseEntity.getBody());
                break;
            }
        } catch (RestClientException ex) {
            if (!hostListIter.hasNext()) {
                throw ex;
            }
            logger.debug("getJSONString() : I/O exception {} occurs when processing url={} ", ex.getMessage(),
                    (host + url));
        }
    }

    return response;
}