RestTemplate: returning a List of Entities
Asked Answered
S

5

8

There is a RestFull method that return a List of Menu objects

public ResponseEntity<List<Menu>> getMenus() {
..
}

But I don't know how to get them from the RestTemplate, getting the class from ResponseEntity>

ResponseEntity<List<Menu>> response = restTemplate
                  .exchange("http://127.0.0.1:8080/elcor/api/users/1/menus", HttpMethod.GET, entity,  ResponseEntity<List<Menu>>.getClass());
Statolatry answered 26/5, 2018 at 8:32 Comment(0)
G
17

Try use ParameterizedTypeReference

ResponseEntity<List<Menu>> response = restTemplate
       .exchange("URI", HttpMethod.GET, entity,  new ParameterizedTypeReference<List<Menu>>() {
 });
Goodden answered 26/5, 2018 at 8:39 Comment(3)
what is entity in above method ?Sherer
Late to the party, but someone else might find this useful: entity is the request object (that is being sent in the body as payload). See below my full answearStulin
As the type is implied by the response variable the type doesn't need to be specified on the right side of the assignment: new ParameterizedTypeReference<> is sufficientMarshmallow
D
3

Try this, It worked for me to getting List of Objects with RestTemplate in Spring

    RestTemplate restTemplate = new RestTemplate();
    try {
        ResponseEntity<List<Claim>> claimResponse = restTemplate.exchange(
                uri, 
                HttpMethod.GET,
                null,
                new ParameterizedTypeReference<List<Claim>>() {});
        if(claimResponse != null && claimResponse.hasBody()){
            claims = claimResponse.getBody();
        }
    } catch (RestClientException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } 
Draft answered 12/9, 2019 at 10:47 Comment(0)
C
3

I've been trying to come up with some generic approach to encapsulate such functionality and use it across my current project. Finally I found out how to do this.

public static <T> List<T> getForList(RestTemplate restTemplate, String url, Class<T> cls, Object... uriVariables) {
    ObjectMapper mapper = new ObjectMapper();
    CollectionType type = mapper.getTypeFactory().constructCollectionType(List.class, cls);
    return restTemplate.<List<T>>exchange(url, HttpMethod.GET, null,
                ParameterizedTypeReference.forType(type), uriVariables)
        .getBody();
}
Cy answered 22/10, 2019 at 15:48 Comment(0)
K
2

You can simply use an array

ResponseEntity<Menu[]> response = restTemplate.exchange("URI", HttpMethod.GET, entity, Menu[].class);
Kuroshio answered 30/12, 2022 at 9:33 Comment(0)
S
1

Somebody else might be confused, so here is a more detailed answer:

private ResponseEntity<List<ResponseDto>> sendRequest(List<RequestDto> requestList) {
    String URL = "http://localhost:8080/endpoint"; // my endpoint

    HttpHeaders headers = new HttpHeaders(); //here you set any headers you need
    headers.setContentType(MediaType.APPLICATION_JSON);

    HttpEntity<List<RequestDto>> request = new HttpEntity<>(requestList, headers); // create the entity object you need to pass as a request object. In my case, it's an array of objects
    return restTemplate.exchange(URL, HttpMethod.POST, request, new ParameterizedTypeReference<List<ResponseDto>>() {
    });
}

In the last line, as the restTemplate.postForEntity(...) does not allow for Collections of elements as a response, we use the exchange(...) method. Its parameters are:

  • URL -> String object, the endpoint for the request
  • method -> HttpMethod object (GET, POST, PUT, PATCH etc)
  • requestEntity -> HttpEntity object, the one that is being created above (mine was called request). It has both the headers for the request and the payload/body
  • responseType -> it's the 4th argument, a ParameterizedTypeReference abstract class. This one is used when the returned type is a Collection, not a simple array or just an object. When the endpoint returns a collection of objects, you cannot do something like Collection<ResponseDto>.class because it's impossible

Another workaround, if you don't need the ResponseEntity object itself, but only the result object, you can do something like

ResponseEntity<ResponseDto[]> responseEntity = restTemplate.postForEntity(URL, request, ResponseDto[].class); // convert the response body to a simple array, not Collection
return Arrays.asList(responseEntity.getBody()); // convert to Collection if needed
Stulin answered 6/9, 2022 at 13:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.