Использование Spring RestTemplate Interceptor

Использование перехватчика Spring RestTemplate

1. обзор

В этом руководстве мы узнаем, как реализовать ссылку Spring: / rest-template Interceptor.

Мы рассмотрим пример, в котором мы создадим перехватчик, который добавляет настраиваемый заголовок к ответу.

2. Сценарии использования перехватчика

Помимо модификации заголовка, некоторые из других случаев использования перехватчикаRestTemplate:

  • Регистрация запросов и ответов

  • Повторное выполнение запросов с настраиваемой стратегией отката

  • Отказ в запросе на основе определенных параметров запроса

  • Изменение URL-адреса запроса

3. Создание перехватчика

В большинстве парадигм программирования среда Springinterceptors are an essential part that enables programmers to control the execution by intercepting it. также поддерживает множество перехватчиков для различных целей.

SpringRestTemplate позволяет нам добавлять перехватчики, реализующие интерфейсClientHttpRequestInterceptor. Методintercept(HttpRequest, byte[], ClientHttpRequestExecution) этого интерфейса перехватит данный запрос и вернет ответ, предоставив нам доступ к объектамrequest,body иexecution.

Мы будем использовать аргументClientHttpRequestExecution для фактического выполнения и передать запрос в последующую цепочку процессов.

В качестве первого шага создадим класс-перехватчик, реализующий интерфейсClientHttpRequestInterceptor:

public class RestTemplateHeaderModifierInterceptor
  implements ClientHttpRequestInterceptor {

    @Override
    public ClientHttpResponse intercept(
      HttpRequest request,
      byte[] body,
      ClientHttpRequestExecution execution) throws IOException {

        ClientHttpResponse response = execution.execute(request, body);
        response.getHeaders().add("Foo", "bar");
        return response;
    }
}

Our interceptor will be invoked for every incoming request, и он будет добавлять настраиваемый заголовокFoo к каждому ответу после завершения выполнения и возврата.

Поскольку методintercept() включает в себя аргументыrequest иbody, также возможно внести какие-либо изменения в запрос или даже запретить выполнение запроса на основе определенных условий.

4. НастройкаRestTemplate

Теперь, когда мы создали наш перехватчик, давайте создадим bean-компонентRestTemplate и добавим к нему наш перехватчик:

@Configuration
public class RestClientConfig {

    @Bean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplate();

        List interceptors
          = restTemplate.getInterceptors();
        if (CollectionUtils.isEmpty(interceptors)) {
            interceptors = new ArrayList<>();
        }
        interceptors.add(new RestTemplateHeaderModifierInterceptor());
        restTemplate.setInterceptors(interceptors);
        return restTemplate;
    }
}

В некоторых случаях к объектуRestTemplate могут быть уже добавлены перехватчики. Поэтому, чтобы убедиться, что все работает должным образом, наш код инициализирует список перехватчиков, только если он пуст.

Как показывает наш код, мы используем конструктор по умолчанию для создания объектаRestTemplate, но есть некоторые сценарии, когда нам нужно дважды прочитать поток запроса / ответа.

Например, если мы хотим, чтобы наш перехватчик функционировал как регистратор запросов / ответов, то нам нужно прочитать его дважды - первый раз перехватчиком и второй раз клиентом.

Реализация по умолчанию позволяет нам читать поток ответов только один раз. Для обслуживания таких конкретных сценариев Spring предоставляет специальный класс под названиемBufferingClientHttpRequestFactory.. Как следует из названия, этот класс буферизует запрос / ответ в памяти JVM для многократного использования.

Вот как инициализируется объектRestTemplate с использованиемBufferingClientHttpRequestFactory для включения кэширования потока запросов / ответов:

RestTemplate restTemplate
  = new RestTemplate(
    new BufferingClientHttpRequestFactory(
      new SimpleClientHttpRequestFactory()
    )
  );

5. Тестирование нашего примера

Вот тестовый пример JUnit для тестирования нашего перехватчикаRestTemplate:

public class RestTemplateItegrationTest {

    @Autowired
    RestTemplate restTemplate;

    @Test
    public void givenRestTemplate_whenRequested_thenLogAndModifyResponse() {
        LoginForm loginForm = new LoginForm("username", "password");
        HttpEntity requestEntity
          = new HttpEntity(loginForm);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        ResponseEntity responseEntity
          = restTemplate.postForEntity(
            "http://httpbin.org/post", requestEntity, String.class
          );

        assertThat(
          responseEntity.getStatusCode(),
          is(equalTo(HttpStatus.OK))
        );
        assertThat(
          responseEntity.getHeaders().get("Foo").get(0),
          is(equalTo("bar"))
        );
    }
}

Здесь мы использовали свободно размещенную службу HTTP-запросов и ответовhttps://httpbin.org , чтобы публиковать наши данные. Этот сервис тестирования вернет наше тело запроса вместе с некоторыми метаданными.

6. Заключение

В этом руководстве рассказывается, как настроить перехватчик и добавить его к объектуRestTemplate. Этот вид перехватчиков также можно использовать для фильтрации, мониторинга и контроля входящих запросов.

Типичным вариантом использования перехватчикаRestTemplate является модификация заголовка, которую мы подробно проиллюстрировали в этой статье.

И, как всегда, вы можете найти пример кода наGithub project. Это проект, основанный на Maven, поэтому его легко импортировать и запускать как есть.