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"; ResponseEntityresponse = 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(); HttpEntityrequest = 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()
Аналогично, давайте рассмотрим операцию, которая вместо возврата полного ресурса просто возвращает Местоположение этого вновь созданного ресурса:
HttpEntityrequest = new HttpEntity<>(new Foo("bar")); URI location = restTemplate .postForLocation(fooResourceUrl, request); assertThat(location, notNullValue());
5.3. API exchange()
Давайте посмотрим, как сделать публикацию с помощью более общего exchange API:
RestTemplate restTemplate = new RestTemplate(); HttpEntityrequest = 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 :
MultiValueMapmap= new LinkedMultiValueMap<>(); map.add("id", "1");
Затем мы создаем запрос, используя HttpEntity экземпляр :
HttpEntity> request = new HttpEntity<>(map, headers);
Наконец, мы можем подключиться к службе REST, вызвав RestTemplate.postForEntity() на конечной точке: /|/foos /форма
ResponseEntityresponse = restTemplate.postForEntity( fooResourceUrl+"/form", request , String.class); assertThat(response.getStatusCode(), is(HttpStatus.CREATED));
6. Используйте ОПЦИИ для получения Разрешенных операций
Далее мы кратко рассмотрим использование запроса ОПЦИЙ и рассмотрим разрешенные операции с определенным URI с использованием такого запроса; API-интерфейс optionsForAllow :
SetoptionsForAllow = 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(); HttpEntityrequestUpdate = 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()); }; }
Далее мы создаем ресурс с запросом на публикацию:
ResponseEntityresponse = 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 .