Course – LS (cat=HTTP Client-Side)

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE

1. Introduction

The RestTemplate class is the central tool for performing client-side HTTP operations in Spring. It provides several utility methods for building HTTP requests and handling responses.

And since RestTemplate integrates well with Jackson, it can serialize/deserialize most objects to and from JSON without much effort. However, working with collections of objects is not so straightforward.

In this tutorial, we’ll learn how to use RestTemplate to GET and POST a list of objects.

Further reading:

Spring RestTemplate Error Handling

Learn how to handle errors with Spring's RestTemplate

RestTemplate Post Request with JSON

Learn how to use Spring's RestTemplate to send requests with JSON content.

2. Example Service

We’ll be using an employee API that has two HTTP endpoints, get all and create:

  • GET /employees
  • POST /employees

For communication between the client and server, we’ll use a simple DTO to encapsulate basic employee data:

public class Employee {
    public long id;
    public String title;

    // standard constructor and setters/getters
}

Now we’re ready to write code that uses RestTemplate to get and create lists of Employee objects.

3. Get a List of Objects With RestTemplate

Normally when calling GET, we can use one of the simplified methods in RestTemplate, such as:

getForObject(URI url, Class<T> responseType)

This sends a request to the specified URI using the GET verb, and converts the response body into the requested Java type. This works great for most classes, but it has a limitation; we can’t send lists of objects.

The problem is due to type erasure with Java generics. When the application is running, it has no knowledge of what type of object is in the list. This means the data in the list can’t be deserialized into the appropriate type.

Luckily, we have two options to get around this.

3.1. Using Arrays

First, we can use RestTemplate.getForEntity() to GET an array of objects via the responseType parameter. Whatever class we specify there will match ResponseEntity‘s parameter type:

ResponseEntity<Employee[]> response =
  restTemplate.getForEntity(
  "http://localhost:8080/employees/",
  Employee[].class);
Employee[] employees = response.getBody();

We could also have used RestTemplate.exchange to achieve the same result.

Note that the collaborator doing the heavy lifting here is ResponseExtractor, so if we need further customization, we can call execute and provide our own instance.

3.2. Using a Wrapper Class

Some APIs will return a top-level object that contains the list of employees instead of returning the list directly. To handle this situation, we can use a wrapper class that contains the list of employees.

public class EmployeeList {
    private List<Employee> employees;

    public EmployeeList() {
        employees = new ArrayList<>();
    }

    // standard constructor and getter/setter
}

Now we can use the simpler getForObject() method to get the list of employees:

EmployeeList response = restTemplate.getForObject(
  "http://localhost:8080/employees",
  EmployeeList.class);
List<Employee> employees = response.getEmployees();

This code is much simpler, but requires an additional wrapper object.

4. Post a List of Objects With RestTemplate

Now let’s look at how to send a list of objects from our client to the server. Just like above, RestTemplate provides a simplified method for calling POST:

postForObject(URI url, Object request, Class<T> responseType)

This sends an HTTP POST to the given URI, with the optional request body, and converts the response into the specified type. Unlike the GET scenario above, we don’t have to worry about type erasure.

This is because now we’re going from Java objects to JSON. The list of objects and their type are known by the JVM, so they’ll be properly serialized:

List<Employee> newEmployees = new ArrayList<>();
newEmployees.add(new Employee(3, "Intern"));
newEmployees.add(new Employee(4, "CEO"));

restTemplate.postForObject(
  "http://localhost:8080/employees/",
  newEmployees,
  ResponseEntity.class);

4.1. Using a Wrapper Class

If we need to use a wrapper class to be consistent with the GET scenario above, that’s simple too. We can send a new list using RestTemplate:

List<Employee> newEmployees = new ArrayList<>();
newEmployees.add(new Employee(3, "Intern"));
newEmployees.add(new Employee(4, "CEO"));

restTemplate.postForObject(
  "http://localhost:8080/employees",
  new EmployeeList(newEmployees),
  ResponseEntity.class);

5. Conclusion

Using RestTemplate is a simple way of building HTTP clients to communicate with our services.

It provides a number of methods for working with every HTTP method and simple objects. With a little bit of extra code, we can easily use it to work with lists of objects.

As usual, the complete code is available in the Github project.

Course – LS (cat=HTTP Client-Side)

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE
res – HTTP Client (eBook) (cat=Http Client-Side)
Comments are closed on this article!