← Назад к вопросам

Что такое 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

ПараметрRestTemplateWebClient
СинхронныйДаНет (асинхронный)
ПростотаВысокаяСредняя
ПроизводительностьНормальнаяВысокая
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 код