RestTemplate предусматривает API более высокого уровня в отличие от клиентских библиотек HTTP. Он позволяет с легкостью вызывать конечные точки REST в одной строке. Он раскрывает следующие группы перегруженных методов:
| Группа методов | Описание |
|---|---|
|
|
Получает представление через метод GET. |
|
|
Получает |
|
|
Получает все заголовки для ресурса через метод HEAD. |
|
|
Создает новый ресурс через метод POST и возвращает заголовок |
|
|
Создает новый ресурс через метод POST и возвращает представление из ответа. |
|
|
Создает новый ресурс через метод POST и возвращает представление из ответа. |
|
|
Создает или обновляет ресурс через метод PUT. |
|
|
Обновляет ресурс через метод PATCH и возвращает представление из ответа. Обратите внимание, что |
|
|
Удаляет ресурсы по указанному URI-идентификатору через метод DELETE. |
|
|
Получает допустимые HTTP-методы для ресурса через метод ALLOW. |
|
|
Более обобщенная (и менее консервативная) версия предыдущих методов, которая обеспечивает дополнительную гибкость, если это необходимо. Он принимает Эти методы позволяют использовать |
|
|
Наиболее обобщенный способ выполнения запроса, с полным контролем над подготовкой запроса и извлечением ответа через интерфейсы обратного вызова. |
Инициализация
Конструктор по умолчанию использует java.net.HttpURLConnection для выполнения запросов. Можно перейти на другую HTTP-библиотеку с реализацией ClientHttpRequestFactory. Имеется встроенная поддержка для:
-
Apache HttpComponents
-
Netty
-
OkHttp
Например, чтобы перейти на Apache HttpComponents, можно сделать следующее:
RestTemplate template = new RestTemplate(new HttpComponentsClientHttpRequestFactory());
Каждая ClientHttpRequestFactory открывает параметры конфигурации, специфичные для базовой клиентской HTTP-библиотеки – например, для учетных данных, пула соединений и другой информации.
java.net для HTTP-запросов может привести к исключению при доступе к статусу ответа, который представляет собой ошибку (например, 401). Если это проблема, то переключитесь на другую HTTP-библиотеку клиента.
URI-идентификаторы
Многие методы RestTemplate принимают URI-шаблон и переменные URI-шаблона либо как аргумент переменной String, либо как Map<String,String>.
В следующем примере используется аргумент переменной String:
String result = restTemplate.getForObject(
"https://example.com/hotels/{hotel}/bookings/{booking}", String.class, "42", "21");
В следующем примере используется Map<String, String>:
Map<String, String> vars = Collections.singletonMap("hotel", "42");
String result = restTemplate.getForObject(
"https://example.com/hotels/{hotel}/rooms/{hotel}", String.class, vars);
Помните, что URI-шаблоны автоматически кодируются, как показано в следующем примере:
restTemplate.getForObject("https://example.com/hotel list", String.class);
// Результат запроса по "https://example.com/hotel%20list"
Можно использовать свойство uriTemplateHandler шаблона RestTemplate для настройки кодирования URI-идентификаторов. Кроме того, можно подготовить java.net.URI и передать его в один из методов RestTemplate, который принимает URI.
Подробнее о работе с URI-идентификаторами и их кодировании см. в разделе "URI-ссылки".
Заголовки
Вы можете использовать методы exchange() для задания заголовков запроса, как показано в следующем примере:
String uriTemplate = "https://example.com/hotels/{hotel}";
URI uri = UriComponentsBuilder.fromUriString(uriTemplate).build(42);
RequestEntity<Void> requestEntity = RequestEntity.get(uri)
.header("MyRequestHeader", "MyValue")
.build();
ResponseEntity<String> response = template.exchange(requestEntity, String.class);
String responseHeader = response.getHeaders().getFirst("MyResponseHeader");
String body = response.getBody();
Можно получать заголовки ответа через множество вариантов методов RestTemplate, которые возвращают ResponseEntity.
Тело
Объекты, передаваемые в методы RestTemplate и возвращаемые из них, преобразуются в сырое содержимое и обратно с помощью HttpMessageConverter.
При методе POST объект ввода сериализуется в тело запроса, как показано в следующем примере:
URI location = template.postForLocation("https://example.com/people", person);
Вам не нужно явно устанавливать заголовок Content-Type для запроса. В большинстве случаев можно найти совместимый преобразователь сообщений на основе типа исходного Object, и выбранный преобразователь сообщений будет устанавливать тип содержимого соответствующим образом. Если необходимо, то можно использовать методы exchange, чтобы явно указать заголовок запроса Content-Type, а это, в свою очередь, влияет на то, какой преобразователь сообщений будет выбран.
При методе GET тело ответа десериализуется в Object вывода, как показано в следующем примере:
Person person = restTemplate.getForObject("https://example.com/people/{id}", Person.class, 42);
Заголовок Accept запроса явно устанавливать не требуется. В большинстве случаев на основе ожидаемого типа ответа можно найти совместимый преобразователь сообщений, который затем поможет заполнить заголовок Accept. При необходимости можно использовать методы exchange для явного указания заголовка Accept.
По умолчанию RestTemplate регистрирует все встроенные преобразователи сообщений в зависимости от результатов проверок classpath, которые помогают определить, какие дополнительные библиотеки преобразования присутствуют. Вы также можете задать используемые преобразователи сообщений явным образом.
Преобразование сообщений
Модуль spring-web содержит контракт HttpMessageConverter для чтения и записи тела HTTP-запросов и ответов через InputStream и OutputStream. Экземпляры HttpMessageConverter используются на стороне клиента (например, в RestTemplate) и на стороне сервера (например, в REST-контроллерах Spring MVC).
Конкретные реализации для основных типов медиа (MIME) предусмотрены во фреймворке и по умолчанию регистрируются в RestTemplate на стороне клиента и в RequestMappingHandlerAdapter на стороне сервера.
Реализации HttpMessageConverter описаны в следующих разделах. Для всех преобразователей используется тип среды передачи данных по умолчанию, но вы можете переопределить его, установив свойство бина supportedMediaTypes. В следующей таблице описана каждая реализация:
| MessageConverter | Описание |
|---|---|
|
|
Реализация |
|
|
Реализация |
|
|
Реализация |
|
|
Реализация |
|
|
An |
|
|
Реализация |
|
|
Реализация |
|
|
Реализация |
Представления Jackson JSON
Можно задавать Представление в формате JSON через билиотеку Jackson для сериализации исключительно подмножества свойств объекта, как показано в следующем примере:
MappingJacksonValue value = new MappingJacksonValue(new User("eric", "7!jd#h23"));
value.setSerializationView(User.WithoutPasswordView.class);
RequestEntity<MappingJacksonValue> requestEntity =
RequestEntity.post(new URI("https://example.com/user")).body(value);
ResponseEntity<String> response = template.exchange(requestEntity, String.class);
Многокомпонентность
Для отправки многокомпонентных данных необходимо предоставить MultiValueMap<String, Object>, значениями которого могут быть Object для содержимого компонента, Resource для файлового компонента или HttpEntity для содержимого компонента с заголовками. Например:
MultiValueMap<String, Object> parts = new LinkedMultiValueMap<>();
parts.add("fieldPart", "fieldValue");
parts.add("filePart", new FileSystemResource("...logo.png"));
parts.add("jsonPart", new Person("Jason"));
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_XML);
parts.add("xmlPart", new HttpEntity<>(myBean, headers));
В большинстве случаев не требуется задавать Content-Type для каждого компонента. Тип содержимого определяется автоматически на основе HttpMessageWriter, выбранного для сериализации, или, в случае Resource, на основе расширения файла. При необходимости можно явно указать MediaType с использованием функции-обёртки HttpEntity.
Когда MultiValueMap будет готова, можно передать ее в RestTemplate, как показано ниже:
MultiValueMap<String, Object> parts = ...;
template.postForObject("https://example.com/upload", parts, Void.class);
Если MultiValueMap содержит хотя бы одно не-String значение, то Content-Type устанавливается в multipart/form-data с помощью FormHttpMessageConverter. Если MultiValueMap имеет String значения, то Content-Type по умолчанию принимает значение application/x-www-form-urlencoded. При необходимости Content-Type также можно задать явным образом.
Использование шаблона AsyncRestTemplate (устарело)
Шаблон AsyncRestTemplate является устаревшим. Во всех случаях, предусматривающих использование AsyncRestTemplate, используйте WebClient.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ