当前位置: 动力学知识库 > 问答 > 编程问答 >

java - Generics with Spring RESTTemplate

问题描述:

I have a class like that:

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;

}

}

and I use resttemplate as follows:

...

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

Model model = response.getData();

...

However it throws a:

ClassCastException

I read that: Issue when trying to use Jackson in java but didn't help. There are some topics related to my problem etc.: https://jira.springsource.org/browse/SPR-7002 and https://jira.springsource.org/browse/SPR-7023

Any ideas?

PS: My error is that:

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

I think resttemplate can not understand my generic variable and maybe it accepts it as an Object instead of generic T. So it becomes a LinkedHashMap. You can read from it here It says that when explaining from what it marshalls to:

JSON Type | Java Type

object | LinkedHashMap

网友答案:

ParameterizedTypeReference has been introduced in 3.2 M2 to workaround this issue.

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

However, the postForObject/getForObject variant was not introduced.

网友答案:

Do not use generics with RestTemplate. Wrap request and response object with wrapper object that will hide the generics.

网友答案:

The only thing I think you could do is creating a new class that extends Wrapper and uses model as a generic.

class WrapperWithModel extends Wrapper<Model>{};

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

It's not the best solution, but at least you won't have to unmarshall manually the response.

网友答案:

You don't need even a wrapper for this. Try this.

/**
 * 
 * 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;
}
分享给朋友:
您可能感兴趣的文章:
随机阅读: