← Назад к вопросам
Что такое RestTemplate в Spring?
2.0 Middle🔥 161 комментариев
#SOLID и паттерны проектирования#Spring Boot и Spring Data
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
RestTemplate в Spring: HTTP клиент для REST API
RestTemplate — это центральный класс в Spring Framework для простого выполнения синхронных HTTP запросов к REST API. Он предоставляет удобные методы для GET, POST, PUT, DELETE и других HTTP операций.
Основные методы RestTemplate
1. GET запрос
import org.springframework.web.client.RestTemplate;
@Service
public class UserService {
private RestTemplate restTemplate = new RestTemplate();
// Простой GET запрос
public String getUser(Long id) {
String url = "https://api.example.com/users/" + id;
String response = restTemplate.getForObject(url, String.class);
return response;
}
// GET с преобразованием в объект
public User getUserAsObject(Long id) {
String url = "https://api.example.com/users/{id}";
User user = restTemplate.getForObject(url, User.class, id);
return user;
}
// GET с получением полного Response
public ResponseEntity<User> getUserWithStatus(Long id) {
String url = "https://api.example.com/users/{id}";
ResponseEntity<User> response = restTemplate.getForEntity(url, User.class, id);
if (response.getStatusCode() == HttpStatus.OK) {
return response;
}
throw new RuntimeException("User not found");
}
}
2. POST запрос
public User createUser(String name, String email) {
String url = "https://api.example.com/users";
// Подготовка данных
User newUser = new User();
newUser.setName(name);
newUser.setEmail(email);
// POST запрос
User createdUser = restTemplate.postForObject(url, newUser, User.class);
return createdUser;
}
// POST с получением статуса
public ResponseEntity<User> createUserWithStatus(String name, String email) {
String url = "https://api.example.com/users";
User newUser = new User(name, email);
ResponseEntity<User> response = restTemplate.postForEntity(url, newUser, User.class);
return response;
}
// POST с получением Location
public URI createUserAndGetLocation(String name, String email) {
String url = "https://api.example.com/users";
User newUser = new User(name, email);
URI location = restTemplate.postForLocation(url, newUser);
return location; // Возвращает URI нового ресурса
}
3. PUT запрос
public void updateUser(Long id, String newName) {
String url = "https://api.example.com/users/{id}";
User updatedUser = new User();
updatedUser.setName(newName);
// PUT запрос (обновление всего ресурса)
restTemplate.put(url, updatedUser, id);
}
4. DELETE запрос
public void deleteUser(Long id) {
String url = "https://api.example.com/users/{id}";
restTemplate.delete(url, id);
}
5. PATCH запрос
public void patchUser(Long id, String newName) {
String url = "https://api.example.com/users/{id}";
Map<String, Object> patch = new HashMap<>();
patch.put("name", newName);
restTemplate.patchForObject(url, patch, User.class, id);
}
Конфигурация RestTemplate
Способ 1: Через @Bean
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RestClientConfig {
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder
.setConnectTimeout(Duration.ofSeconds(5))
.setReadTimeout(Duration.ofSeconds(10))
.build();
}
}
// Использование
@Service
public class UserService {
@Autowired
private RestTemplate restTemplate;
public User getUser(Long id) {
// Использование
}
}
Способ 2: С кастомными перехватчиками
@Configuration
public class RestClientConfig {
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder
.setConnectTimeout(Duration.ofSeconds(5))
.interceptors((request, body, execution) -> {
request.getHeaders().set("Authorization", "Bearer token");
return execution.execute(request, body);
})
.build();
}
}
Обработка ошибок
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.HttpClientErrorException;
public User getUser(Long id) {
try {
String url = "https://api.example.com/users/{id}";
User user = restTemplate.getForObject(url, User.class, id);
return user;
} catch (HttpClientErrorException.NotFound e) {
logger.error("User not found", e);
throw new ResourceNotFoundException("User with id " + id + " not found");
} catch (HttpClientErrorException.BadRequest e) {
logger.error("Bad request", e);
throw new InvalidRequestException(e.getMessage());
} catch (RestClientException e) {
logger.error("Connection error", e);
throw new ServiceUnavailableException("External service is unavailable", e);
}
}
Заголовки и параметры
// GET с заголовками
public User getUserWithHeaders(Long id) {
String url = "https://api.example.com/users/{id}";
// Подготовка заголовков
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer token123");
headers.set("Accept", "application/json");
// Создание запроса
HttpEntity<String> entity = new HttpEntity<>(headers);
// Выполнение
ResponseEntity<User> response = restTemplate.exchange(
url,
HttpMethod.GET,
entity,
User.class,
id
);
return response.getBody();
}
// POST с заголовками и телом
public User createUserWithHeaders(String name, String email) {
String url = "https://api.example.com/users";
// Подготовка заголовков
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", "Bearer token123");
// Подготовка тела
User newUser = new User(name, email);
HttpEntity<User> entity = new HttpEntity<>(newUser, headers);
// Выполнение
ResponseEntity<User> response = restTemplate.exchange(
url,
HttpMethod.POST,
entity,
User.class
);
return response.getBody();
}
Retry логика
import org.springframework.retry.annotation.Retryable;
import org.springframework.retry.annotation.Backoff;
import org.springframework.web.client.RestClientException;
@Service
public class UserService {
@Retryable(
value = RestClientException.class,
maxAttempts = 3,
backoff = @Backoff(delay = 1000, multiplier = 2)
)
public User getUser(Long id) {
String url = "https://api.example.com/users/{id}";
return restTemplate.getForObject(url, User.class, id);
}
}
Практический пример: Интеграция с внешним API
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
// DTO для внешнего API
@JsonIgnoreProperties(ignoreUnknown = true)
public class ExternalUserDTO {
private Long id;
private String name;
private String email;
// getters, setters
}
// Сервис
@Service
public class ExternalUserService {
private final RestTemplate restTemplate;
private final String externalApiUrl = "https://api.example.com";
public ExternalUserService(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
// Получение пользователя
public ExternalUserDTO getExternalUser(Long id) {
try {
String url = externalApiUrl + "/users/{id}";
return restTemplate.getForObject(url, ExternalUserDTO.class, id);
} catch (HttpClientErrorException.NotFound e) {
logger.warn("External user not found: " + id);
return null;
} catch (RestClientException e) {
logger.error("Error fetching external user", e);
throw new ServiceException("Failed to fetch user from external service", e);
}
}
// Получение списка пользователей
public List<ExternalUserDTO> getAllExternalUsers() {
String url = externalApiUrl + "/users";
ExternalUserDTO[] users = restTemplate.getForObject(url, ExternalUserDTO[].class);
return Arrays.asList(users);
}
// Создание пользователя
public ExternalUserDTO createExternalUser(String name, String email) {
String url = externalApiUrl + "/users";
ExternalUserDTO newUser = new ExternalUserDTO();
newUser.setName(name);
newUser.setEmail(email);
return restTemplate.postForObject(url, newUser, ExternalUserDTO.class);
}
}
// Контроллер
@RestController
@RequestMapping("/api/sync")
public class SyncController {
private final ExternalUserService externalUserService;
@GetMapping("/users/{id}")
public ResponseEntity<User> syncUser(@PathVariable Long id) {
ExternalUserDTO externalUser = externalUserService.getExternalUser(id);
if (externalUser == null) {
return ResponseEntity.notFound().build();
}
User localUser = convertToLocalUser(externalUser);
return ResponseEntity.ok(localUser);
}
}
RestTemplate vs WebClient
| Параметр | RestTemplate | WebClient |
|---|---|---|
| Синхронный | Да | Нет (асинхронный) |
| Простота | Высокая | Средняя |
| Производительность | Нормальная | Высокая |
| Non-blocking | Нет | Да |
| Spring 5.0+ | Deprecated | Рекомендуется |
| Используется для | Простых запросов | Высоконагруженных систем |
RestTemplate vs OpenFeign
// RestTemplate
@Service
public class UserService {
@Autowired
private RestTemplate restTemplate;
public User getUser(Long id) {
return restTemplate.getForObject("/users/{id}", User.class, id);
}
}
// OpenFeign (более декларативный)
@FeignClient(name = "user-service", url = "https://api.example.com")
public interface UserClient {
@GetMapping("/users/{id}")
User getUser(@PathVariable("id") Long id);
}
Итого
- RestTemplate — синхронный HTTP клиент для REST API
- Простой в использовании — удобные методы для GET, POST, PUT, DELETE
- Flexible — поддерживает заголовки, параметры, перехватчики
- Error handling — встроенная обработка HTTP ошибок
- Deprecated в пользу WebClient — для новых проектов используй WebClient
- Ideal для — простых интеграций, legacy код