Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get list of JSON objects with Spring RestTemplate

People also ask

What is difference between getForObject and getForEntity?

For example, the method getForObject() will perform a GET and return an object. getForEntity() : executes a GET request and returns an object of ResponseEntity class that contains both the status code and the resource as an object. getForObject() : similar to getForEntity() , but returns the resource directly.

Why RestTemplate is deprecated?

RestTemplate provides a synchronous way of consuming Rest services, which means it will block the thread until it receives a response. RestTemplate is deprecated since Spring 5 which means it's not really that future proof.


First define an object to hold the entity coming back in the array.. e.g.

@JsonIgnoreProperties(ignoreUnknown = true)
public class Rate {
    private String name;
    private String code;
    private Double rate;
    // add getters and setters
}

Then you can consume the service and get a strongly typed list via:

ResponseEntity<List<Rate>> rateResponse =
        restTemplate.exchange("https://bitpay.com/api/rates",
                    HttpMethod.GET, null, new ParameterizedTypeReference<List<Rate>>() {
            });
List<Rate> rates = rateResponse.getBody();

The other solutions above will also work, but I like getting a strongly typed list back instead of an Object[].


Maybe this way...

ResponseEntity<Object[]> responseEntity = restTemplate.getForEntity(urlGETList, Object[].class);
Object[] objects = responseEntity.getBody();
MediaType contentType = responseEntity.getHeaders().getContentType();
HttpStatus statusCode = responseEntity.getStatusCode();

Controller code for the RequestMapping

@RequestMapping(value="/Object/getList/", method=RequestMethod.GET)
public @ResponseBody List<Object> findAllObjects() {

    List<Object> objects = new ArrayList<Object>();
    return objects;
}

ResponseEntity is an extension of HttpEntity that adds a HttpStatus status code. Used in RestTemplate as well @Controller methods. In RestTemplate this class is returned by getForEntity() and exchange().


For me this worked

Object[] forNow = template.getForObject("URL", Object[].class);
    searchList= Arrays.asList(forNow);

Where Object is the class you want


You can create POJO for each entry like,

class BitPay{
private String code;
private String name;
private double rate;
}

then using ParameterizedTypeReference of List of BitPay you can use as:

RestTemplate restTemplate = new RestTemplate();
ResponseEntity<List<Employee>> response = restTemplate.exchange(
  "https://bitpay.com/api/rates",
  HttpMethod.GET,
  null,
  new ParameterizedTypeReference<List<BitPay>>(){});
List<Employee> employees = response.getBody();

If you would prefer a List of POJOs, one way to do it is like this:

class SomeObject {
    private int id;
    private String name;
}

public <T> List<T> getApi(final String path, final HttpMethod method) {     
    final RestTemplate restTemplate = new RestTemplate();
    final ResponseEntity<List<T>> response = restTemplate.exchange(
      path,
      method,
      null,
      new ParameterizedTypeReference<List<T>>(){});
    List<T> list = response.getBody();
    return list;
}

And use it like so:

 List<SomeObject> list = someService.getApi("http://localhost:8080/some/api",HttpMethod.GET);

Explanation for the above can be found here (https://www.baeldung.com/spring-rest-template-list) and is paraphrased below.

"There are a couple of things happening in the code above. First, we use ResponseEntity as our return type, using it to wrap the list of objects we really want. Second, we are calling RestTemplate.exchange() instead of getForObject().

This is the most generic way to use RestTemplate. It requires us to specify the HTTP method, optional request body, and a response type. In this case, we use an anonymous subclass of ParameterizedTypeReference for the response type.

This last part is what allows us to convert the JSON response into a list of objects that are the appropriate type. When we create an anonymous subclass of ParameterizedTypeReference, it uses reflection to capture information about the class type we want to convert our response to.

It holds on to this information using Java’s Type object, and we no longer have to worry about type erasure."


After multiple tests, this is the best way I found :)

Set<User> test = httpService.get(url).toResponseSet(User[].class);

All you need there

public <T> Set<T> toResponseSet(Class<T[]> setType) {
    HttpEntity<?> body = new HttpEntity<>(objectBody, headers);
    ResponseEntity<T[]> response = template.exchange(url, method, body, setType);
    return Sets.newHashSet(response.getBody());
}