Что такое RestTemplate в Spring и как его использовать?

Ответ

RestTemplate — это синхронный, блокирующий HTTP-клиент в Spring Framework для вызова RESTful веб-сервисов. Начиная с Spring 5, он находится в режиме поддержки, и для нового кода рекомендуется использовать реактивный WebClient.

Основные методы (по HTTP-глаголам):

  • getForObject(), getForEntity() — для GET-запросов.
  • postForObject(), postForEntity(), postForLocation() — для POST-запросов.
  • put() — для PUT-запросов.
  • delete() — для DELETE-запросов.
  • exchange() — универсальный метод для любых запросов с полным контролем над заголовками и телом.

Пример GET-запроса:

import org.springframework.web.client.RestTemplate;
import org.springframework.http.ResponseEntity;

RestTemplate restTemplate = new RestTemplate();
String url = "https://api.example.com/users/{id}";

// Получение объекта (автоматическая десериализация JSON в POJO)
User user = restTemplate.getForObject(url, User.class, 1);

// Получение ResponseEntity с метаданными ответа (статус, заголовки)
ResponseEntity<User> response = restTemplate.getForEntity(url, User.class, 1);
if (response.getStatusCode().is2xxSuccessful()) {
    User userFromResponse = response.getBody();
}

Пример POST-запроса с телом и заголовками:

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", "Bearer token123");

User newUser = new User("John Doe");
HttpEntity<User> request = new HttpEntity<>(newUser, headers);

User createdUser = restTemplate.postForObject("https://api.example.com/users", request, User.class);

Настройка: RestTemplate можно настроить через RestTemplateBuilder или создав бины для ClientHttpRequestFactory (например, HttpComponentsClientHttpRequestFactory для Apache HttpClient) и HttpMessageConverter (для обработки JSON, XML).

Недостатки (почему WebClient предпочтительнее):

  • Синхронный и блокирующий: Каждый вызов занимает поток на всё время запроса-ответа, что плохо масштабируется.
  • Ограниченная поддержка реактивных потоков.
  • Менее функциональный fluent API по сравнению с WebClient.

Ответ 18+ 🔞

А, RestTemplate, ёпта, классика жанра! Ну это типа как старый, добрый, но уже слегка засаленный Запорожец в гараже — ездит, гремит, но все вокруг уже на Теслах катаются.

Короче, это такой синхронный, блокирующий HTTP-клиентик в Spring. Ты ему говоришь: «Сходи туда-то», а он тебя нахуй посылает и замирает, пока не получит ответ или пока у него таймаут не кончится. Весь твой поток он занимает, как будто это его личная скамейка в парке. С Spring 5 его, блядь, отправили в тихую ссылку — типа «поддерживаем, но новое говно на нём не пиши». Вместо него теперь модный, реактивный WebClient, который не блокируется и может делать кучу запросов одновременно, как шлюха на распродаже.

Основные его пиздюлины (по глаголам HTTP):

  • getForObject(), getForEntity() — чтобы что-то получить (GET).
  • postForObject(), postForEntity() — чтобы что-то отправить (POST).
  • put() — чтобы что-то обновить (PUT).
  • delete() — чтобы что-то удалить (DELETE).
  • exchange() — это универсальная дубина, когда надо полный контроль: заголовки, тело, всё на свете.

Вот смотри, как простой GET-запрос выглядит:

import org.springframework.web.client.RestTemplate;
import org.springframework.http.ResponseEntity;

RestTemplate restTemplate = new RestTemplate();
String url = "https://api.example.com/users/{id}";

// Вариант попроще — сразу объект получаем
User user = restTemplate.getForObject(url, User.class, 1);

// Вариант поумнее — получаем ResponseEntity, а там и статус, и заголовки, и тело
ResponseEntity<User> response = restTemplate.getForEntity(url, User.class, 1);
if (response.getStatusCode().is2xxSuccessful()) {
    User userFromResponse = response.getBody(); // Вот тут наше сокровище
}

А вот POST-запрос, где мы уже голову морочим с заголовками:

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON); // Говорим, что шлём JSON
headers.set("Authorization", "Bearer token123"); // А это наш пропуск в закрытый клуб

User newUser = new User("John Doe");
HttpEntity<User> request = new HttpEntity<>(newUser, headers); // Упаковываем тело и заголовки в одну коробку

User createdUser = restTemplate.postForObject("https://api.example.com/users", request, User.class);

Настроить его можно через RestTemplateBuilder или наколхозить бины для фабрики запросов (ClientHttpRequestFactory) и конвертеров (HttpMessageConverter), чтобы он понимал JSON, XML и прочую хуйню.

А теперь, блядь, почему его все поливают говном:

  • Синхронный и блокирующий. Каждый запрос — это как стоять в очереди в совке за колбасой. Пока один не обслужат, следующий нихуя не двигается. Масштабируется это дело хуже, чем моя мотивация в понедельник утром.
  • Реактивность ему, как собаке пятая нога. WebClient в этом плане — просто бог.
  • API у него не такой гибкий и красивый, как у того же WebClient. Там можно цепочки методов строить, а тут — вызывай конкретный метод и молись.

В общем, инструмент рабочий, но уже пахнет нафталином. Для легаси-проектов — ок, для нового кода — лучше посмотреть в сторону WebClient, а то охуеешь потом потоки разгребать.