Получить и опубликовать списки объектов с RestTemplate

Получить и опубликовать списки объектов с RestTemplate

1. Вступление

КлассRestTemplate - это центральный инструмент для выполнения клиентских HTTP-операций в Spring. Он предоставляет несколько служебных методов для построения HTTP-запросов и обработки ответов.

И, посколькуRestTemplate хорошо интегрируется сJackson,, он может сериализовать / десериализовать большинство объектов в JSON и из него без особых усилий. Однакоworking with collections of objects is not so straightforward.

В этом руководстве мы увидим, как использоватьRestTemplate как дляGET, так и дляPOST списка объектов.

Дальнейшее чтение:

Spring RestTemplate Обработка ошибок

Узнайте, как обрабатывать ошибки с помощью Spring RestTemplate

Read more

RestTemplate Опубликовать запрос с JSON

Узнайте, как использовать Spring RestTemplate для отправки запросов с содержимым JSON.

Read more

2. Пример службы

Мы будем использовать API сотрудника, который имеет две конечные точки HTTP - получить все и создать:

  • GET / сотрудники

  • POST / сотрудники

Для связи между клиентом и сервером мы будем использовать простой DTO для инкапсуляции основных данных о сотрудниках:

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

    // standard constructor and setters/getters
}

Теперь мы готовы написать код, который используетRestTemplate для получения и создания списков объектовEmployee.

3. Получить список объектов сRestTemplate

Обычно при вызове GET вы можете использовать один из упрощенных методов вRestTemplate, например:

getForObject (URL-адрес URI, Class responseType)

Это отправляет запрос на указанный URI с помощью глагола GET и преобразует тело ответа в запрошенный тип Java. Это отлично работает для большинства классов, но имеет ограничение:we cannot send lists of objects.

Проблема связана с стиранием типов с помощью дженериков Java. Когда приложение работает, оно не знает, какой тип объекта находится в списке. This means the data in the list cannot be deserialized into the appropriate type.с

К счастью, у нас есть два варианта, чтобы обойти это.

3.1. Использование массивов

Во-первых, мы можем использоватьRestTemplate.getForObject() to GET для получения массива объектов через параметрresponseType. Какой быclass мы там ни указали, он будет соответствовать типу параметраResponseEntity:

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

Кроме того, мы могли бы использоватьRestTemplate.exchange для достижения того же результата.

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

3.2. Использование класса Wrapper

Некоторые API возвращают объект верхнего уровня, который содержит список сотрудников, вместо того, чтобы возвращать список напрямую. Чтобы справиться с этой ситуацией, мы можем использовать класс-оболочку, который содержит список сотрудников.

public class EmployeeList {
    private List employees;

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

    // standard constructor and getter/setter
}

Теперь мы можем использовать более простой методgetForObject() для получения списка сотрудников:

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

Этот код намного проще, но требует дополнительного объекта-оболочки.

4. Опубликовать список объектов сRestTemplate

Теперь давайте посмотрим, как отправить список объектов от нашего клиента на сервер. Как и выше,RestTemplate предоставляет упрощенный метод вызова POST:

postForObject (URL-адрес URI, запрос объекта, класс responseType)

Это отправляет HTTP-запрос POST на указанный URI с необязательным телом запроса и преобразует ответ в указанный тип. В отличие от сценария GET, описанного выше,we don’t have to worry about type erasure.

Это потому, что теперь мы переходим от объектов Java к JSON. Список объектов и их тип известны JVM и поэтому должны быть сериализованы правильно:

List 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. Использование класса Wrapper

Если нам нужно использовать класс-оболочку, чтобы соответствовать описанному выше сценарию GET, это тоже просто. Мы можем отправить новый список, используяRestTemplate:

List 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. Заключение

Использование RestTemplate - это простой способ создания HTTP-клиентов для связи с вашими сервисами.

Он предоставляет ряд методов для работы с каждым методом HTTP и простыми объектами. С небольшим количеством дополнительного кода мы можем легко использовать его для работы со списками объектов.

Как обычно, полный код доступен вGithub project.