Рубрики
Без рубрики

Руководство по повторной сборке

Узнайте, как использовать Spring RestTemplate для использования API с использованием всех основных HTTP-глаголов.

Автор оригинала: baeldung.

1. Обзор

В этом уроке мы проиллюстрируем широкий спектр операций, в которых можно использовать клиент Spring REST — RestTemplate , и использовать его хорошо.

Для API-части всех примеров мы будем запускать службу RESTful из здесь .

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

Базовая аутентификация с помощью шаблона RestTemplate

RestTemplate с дайджест-аутентификацией

Изучение тестовой панели Spring Boot

2. Уведомление Об Устаревании

Начиная с Spring Framework 5, наряду со стеком WebFlux, Spring представила новый HttpClient под названием WebClient .

Веб-клиент – это современный, альтернативный HTTP-клиент RestTemplate . Он не только предоставляет традиционный синхронный API, но также поддерживает эффективный неблокирующий и асинхронный подход.

Тем не менее, если мы разрабатываем новые приложения или переносим старые, рекомендуется использовать WebClient . Продвигаясь вперед, RestTemplate будет устаревшим в будущих версиях.

3. Используйте GET для извлечения ресурсов

3.1. Получить обычный JSON

Давайте начнем с простого и поговорим о запросах GET с краткого примера использования getForEntity() API :

RestTemplate restTemplate = new RestTemplate();
String fooResourceUrl
  = "http://localhost:8080/spring-rest/foos";
ResponseEntity response
  = restTemplate.getForEntity(fooResourceUrl + "/1", String.class);
assertThat(response.getStatusCode(), equalTo(HttpStatus.OK));

Обратите внимание , что у нас есть полный доступ к ответу HTTP , поэтому мы можем выполнять такие действия, как проверка кода состояния, чтобы убедиться, что операция прошла успешно, или работа с фактическим текстом ответа:

ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(response.getBody());
JsonNode name = root.path("name");
assertThat(name.asText(), notNullValue());

Мы работаем с телом ответа в качестве стандартной строки здесь и используем Джексона (и структуру узлов JSON, которую предоставляет Джексон) для проверки некоторых деталей.

3.2. Получение POJO Вместо JSON

Мы также можем сопоставить ответ непосредственно с ресурсом, чтобы:

public class Foo implements Serializable {
    private long id;

    private String name;
    // standard getters and setters
}

Теперь мы можем просто использовать getForObject API в шаблоне:

Foo foo = restTemplate
  .getForObject(fooResourceUrl + "/1", Foo.class);
assertThat(foo.getName(), notNullValue());
assertThat(foo.getId(), is(1L));

4. Используйте HEAD для извлечения заголовков

Давайте теперь быстро рассмотрим использование HEAD, прежде чем переходить к более распространенным методам.

Мы собираемся использовать headForHeaders() API здесь:

HttpHeaders httpHeaders = restTemplate.headForHeaders(fooResourceUrl);
assertTrue(httpHeaders.getContentType().includes(MediaType.APPLICATION_JSON));

5. Используйте СООБЩЕНИЕ для создания ресурса

Для того чтобы создать новый ресурс в API, мы можем эффективно использовать Постфорлокация() , postForObject() или Постфактум() АПИС.

Первый возвращает URI вновь созданного ресурса, в то время как второй возвращает сам ресурс.

5.1. API postForObject()

RestTemplate restTemplate = new RestTemplate();

HttpEntity request = new HttpEntity<>(new Foo("bar"));
Foo foo = restTemplate.postForObject(fooResourceUrl, request, Foo.class);
assertThat(foo, notNullValue());
assertThat(foo.getName(), is("bar"));

5.2. API postForLocation()

Аналогично, давайте рассмотрим операцию, которая вместо возврата полного ресурса просто возвращает Местоположение этого вновь созданного ресурса:

HttpEntity request = new HttpEntity<>(new Foo("bar"));
URI location = restTemplate
  .postForLocation(fooResourceUrl, request);
assertThat(location, notNullValue());

5.3. API exchange()

Давайте посмотрим, как сделать публикацию с помощью более общего exchange API:

RestTemplate restTemplate = new RestTemplate();
HttpEntity request = new HttpEntity<>(new Foo("bar"));
ResponseEntity response = restTemplate
  .exchange(fooResourceUrl, HttpMethod.POST, request, Foo.class);
 
assertThat(response.getStatusCode(), is(HttpStatus.CREATED));
 
Foo foo = response.getBody();
 
assertThat(foo, notNullValue());
assertThat(foo.getName(), is("bar"));

5.4. Отправьте Данные Формы

Далее давайте рассмотрим, как отправить форму с помощью метода POST.

Во-первых, нам нужно установить Тип контента заголовок к приложение/x-www-форма-url-кодированный.

Это гарантирует, что на сервер может быть отправлена большая строка запроса, содержащая пары имя/значение, разделенные & :

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

Мы можем обернуть переменные формы в LinkedMultiValueMap :

MultiValueMap map= new LinkedMultiValueMap<>();
map.add("id", "1");

Затем мы создаем запрос, используя HttpEntity экземпляр :

HttpEntity> request = new HttpEntity<>(map, headers);

Наконец, мы можем подключиться к службе REST, вызвав RestTemplate.postForEntity() на конечной точке: /|/foos /форма

ResponseEntity response = restTemplate.postForEntity(
  fooResourceUrl+"/form", request , String.class);
 
assertThat(response.getStatusCode(), is(HttpStatus.CREATED));

6. Используйте ОПЦИИ для получения Разрешенных операций

Далее мы кратко рассмотрим использование запроса ОПЦИЙ и рассмотрим разрешенные операции с определенным URI с использованием такого запроса; API-интерфейс optionsForAllow :

Set optionsForAllow = restTemplate.optionsForAllow(fooResourceUrl);
HttpMethod[] supportedMethods
  = {HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT, HttpMethod.DELETE};
assertTrue(optionsForAllow.containsAll(Arrays.asList(supportedMethods)));

7. Используйте PUT для обновления ресурса

Далее мы начнем рассматривать PUT и, более конкретно, exchange() API для этой операции, поскольку template.put API довольно прост.

7.1. Простой ОБМЕН С обменом()

Мы начнем с простой операции PUT против API — и имейте в виду, что эта операция не возвращает тело обратно клиенту:

Foo updatedInstance = new Foo("newName");
updatedInstance.setId(createResponse.getBody().getId());
String resourceUrl = 
  fooResourceUrl + '/' + createResponse.getBody().getId();
HttpEntity requestUpdate = new HttpEntity<>(updatedInstance, headers);
template.exchange(resourceUrl, HttpMethod.PUT, requestUpdate, Void.class);

7.2. ПОСТАВЬТЕ С exchange() и запросом Обратного вызова

Далее мы будем использовать обратный вызов запроса для выдачи ПУТ.

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

RequestCallback requestCallback(final Foo updatedInstance) {
    return clientHttpRequest -> {
        ObjectMapper mapper = new ObjectMapper();
        mapper.writeValue(clientHttpRequest.getBody(), updatedInstance);
        clientHttpRequest.getHeaders().add(
          HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
        clientHttpRequest.getHeaders().add(
          HttpHeaders.AUTHORIZATION, "Basic " + getBase64EncodedLogPass());
    };
}

Далее мы создаем ресурс с запросом на публикацию:

ResponseEntity response = restTemplate
  .exchange(fooResourceUrl, HttpMethod.POST, request, Foo.class);
assertThat(response.getStatusCode(), is(HttpStatus.CREATED));

И когда мы обновляем ресурс:

Foo updatedInstance = new Foo("newName");
updatedInstance.setId(response.getBody().getId());
String resourceUrl =fooResourceUrl + '/' + response.getBody().getId();
restTemplate.execute(
  resourceUrl, 
  HttpMethod.PUT, 
  requestCallback(updatedInstance), 
  clientHttpResponse -> null);

8. Используйте команду УДАЛИТЬ, чтобы Удалить ресурс

Чтобы удалить существующий ресурс, мы быстро воспользуемся delete() API:

String entityUrl = fooResourceUrl + "/" + existingResource.getId();
restTemplate.delete(entityUrl);

9. Настройте Время ожидания

Мы можем настроить RestTemplate на тайм-аут, просто используя ClientHttpRequestFactory :

RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());

private ClientHttpRequestFactory getClientHttpRequestFactory() {
    int timeout = 5000;
    HttpComponentsClientHttpRequestFactory clientHttpRequestFactory
      = new HttpComponentsClientHttpRequestFactory();
    clientHttpRequestFactory.setConnectTimeout(timeout);
    return clientHttpRequestFactory;
}

И мы можем использовать HttpClient для получения дополнительных параметров конфигурации:

private ClientHttpRequestFactory getClientHttpRequestFactory() {
    int timeout = 5000;
    RequestConfig config = RequestConfig.custom()
      .setConnectTimeout(timeout)
      .setConnectionRequestTimeout(timeout)
      .setSocketTimeout(timeout)
      .build();
    CloseableHttpClient client = HttpClientBuilder
      .create()
      .setDefaultRequestConfig(config)
      .build();
    return new HttpComponentsClientHttpRequestFactory(client);
}

10. Заключение

В этой статье мы рассмотрели основные HTTP-глаголы, используя RestTemplate для организации запросов с использованием всех этих.

Если вы хотите разобраться в том, как выполнить аутентификацию с помощью шаблона, ознакомьтесь с нашей статьей об основной аутентификации с помощью RestTemplate .

Реализацию всех этих примеров и фрагментов кода можно найти на GitHub .