Usando o Spring RestTemplate Interceptor

Usando o Spring RestTemplate Interceptor

1. Visão geral

Neste tutorial, vamos aprender como implementar um link Spring: / rest-template Interceptor.

Examinaremos um exemplo em que criaremos um interceptor que adiciona um cabeçalho personalizado à resposta.

2. Cenários de uso do interceptador

Além da modificação do cabeçalho, alguns dos outros casos de uso em que um interceptorRestTemplate é útil são:

  • Registro de solicitação e resposta

  • Tentando novamente os pedidos com uma estratégia de retirada configurável

  • Negação de solicitação com base em certos parâmetros de solicitação

  • Alterando o endereço da URL da solicitação

3. Criando o Interceptor

Na maioria dos paradigmas de programação, o frameworkinterceptors are an essential part that enables programmers to control the execution by intercepting it. Spring também suporta uma variedade de interceptores para diferentes propósitos.

SpringRestTemplate nos permite adicionar interceptores que implementam a interfaceClientHttpRequestInterceptor. O métodointercept(HttpRequest, byte[], ClientHttpRequestExecution) dessa interface interceptará a solicitação fornecida e retornará a resposta, dando-nos acesso aos objetosrequest,bodyeexecution.

Estaremos usando o argumentoClientHttpRequestExecution para fazer a execução real e passar a solicitação para a cadeia de processo subsequente.

Como uma primeira etapa, vamos criar uma classe de interceptor que implementa a interfaceClientHttpRequestInterceptor:

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, e adicionará um cabeçalho personalizadoFoo a cada resposta, assim que a execução for concluída e retornada.

Como o métodointercept() incluiurequestebody como argumentos, também é possível fazer qualquer modificação na solicitação ou mesmo negar a execução da solicitação com base em certas condições.

4. Configurando oRestTemplate

Agora que criamos nosso interceptor, vamos criar o beanRestTemplate e adicionar nosso interceptor a ele:

@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;
    }
}

Em alguns casos, pode haver interceptores já adicionados ao objetoRestTemplate. Portanto, para garantir que tudo funcione conforme o esperado, nosso código inicializará a lista de interceptores apenas se estiver vazia.

Como nosso código mostra, estamos usando o construtor padrão para criar o objetoRestTemplate, mas existem alguns cenários em que precisamos ler o fluxo de solicitação / resposta duas vezes.

Por exemplo, se queremos que nosso interceptador funcione como um registrador de solicitação / resposta, precisamos lê-lo duas vezes - a primeira vez pelo interceptador e a segunda pelo cliente.

A implementação padrão nos permite ler o fluxo de resposta apenas uma vez. Para atender a esses cenários específicos, o Spring fornece uma classe especial chamadaBufferingClientHttpRequestFactory.. Como o nome sugere, essa classe armazenará em buffer a solicitação / resposta na memória JVM para uso múltiplo.

Veja como o objetoRestTemplate é inicializado usandoBufferingClientHttpRequestFactory para habilitar o cache de fluxo de solicitação / resposta:

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

5. Testando Nosso Exemplo

Aqui está o caso de teste JUnit para testar nosso interceptorRestTemplate:

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"))
        );
    }
}

Aqui, usamos o serviço de solicitação e resposta HTTP hospedado gratuitamentehttps://httpbin.org para postar nossos dados. Este serviço de teste retornará nosso corpo de solicitação junto com alguns metadados.

6. Conclusão

Este tutorial é sobre como configurar um interceptor e adicioná-lo ao objetoRestTemplate. Esse tipo de interceptador também pode ser usado para filtrar, monitorar e controlar as solicitações recebidas.

Um caso de uso comum para um interceptorRestTemplate é a modificação do cabeçalho - que ilustramos em detalhes neste artigo.

E, como sempre, você pode encontrar o código de exemplo emGithub project. Este é um projeto baseado em Maven, portanto, deve ser fácil importar e executar como está.