Spring

RestTemplate Interceptor활용하기

기록만이살길 2020. 6. 15. 22:15
반응형

1. 개요

이 튜토리얼에서는 Spring RestTemplate Interceptor 를 구현하는 방법을 배웁니다 . 응답에 사용자 정의 헤더를 추가하는 인터셉터를 작성하는 예제를 살펴 보겠습니다.

2. 인터셉터 사용 시나리오

헤더 수정 외에도 RestTemplate 인터셉터가 유용한 다른 사용 사례 는 다음과 같습니다.

  • 요청 및 응답 로깅
  • 구성 가능한 백 오프 전략으로 요청 재시도
  • 특정 요청 매개 변수를 기반으로 요청 거부
  • 요청 URL 주소 변경

3. Custom 인터셉터 만들기

대부분의 프로그래밍 패러다임에서 인터셉터는 프로그래머가 인터셉트를 통해 실행을 제어 할 수 있도록하는 필수 요소입니다. 스프링 프레임 워크는 다양한 목적으로 다양한 인터셉터를 지원합니다.

Spring RestTemplate을 사용하면 ClientHttpRequestInterceptor 인터페이스 를 구현하는 인터셉터를 추가 할 수 있습니다. 이 인터페이스 의 intercept (HttpRequest, byte [], ClientHttpRequestExecution) 메소드는 주어진 요청을 차단하고 request , bodyexecution 객체에 대한 액세스를 제공하여 응답을 반환 합니다.

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

인터셉터는 들어오는 모든 요청에 ​​대해 호출 되며 실행이 완료되고 반환되면 모든 응답에 사용자 정의 헤더 Foo 를 추가 합니다.

intercept () 메소드에는 요청본문 이 인수로 포함되어 있기 때문에 요청에 대한 수정을 수행하거나 특정 조건에 따라 요청 실행을 거부 할 수도 있습니다.

4. RestTemplate 설정

인터셉터를 생성 했으니 RestTemplate bean을 생성 하고 인터셉터를 추가하자 :

@Configuration
public class RestClientConfig {

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

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

경우에 따라 RestTemplate 객체에 인터셉터가 이미 추가되어있을 수 있습니다 . 따라서 모든 것이 예상대로 작동하는지 확인하기 위해 코드는 인터셉터 목록이 비어있는 경우에만 초기화합니다.

코드에서 알 수 있듯이 기본 생성자를 사용하여 RestTemplate 객체 를 만들고 있지만 요청 / 응답 스트림을 두 번 읽어야하는 몇 가지 시나리오가 있습니다.

예를 들어, 인터셉터가 요청 / 응답 로거로서 기능하도록하려면 인터셉터가 처음으로, 클라이언트가 두 번째로 두 번 읽어야합니다.

기본 구현에서는 응답 스트림을 한 번만 읽을 수 있습니다. 이러한 특정 시나리오를 제공하기 위해 Spring은 BufferingClientHttpRequestFactory 라는 특수 클래스를 제공합니다 . 이름에서 알 수 있듯이이 클래스는 여러 용도로 JVM 메모리에서 요청 / 응답을 버퍼링합니다.

다음 은 BufferingClientHttpRequestFactory 를 사용 하여 RestTemplate 객체를 초기화하여 요청 / 응답 스트림 캐싱을 활성화하는 방법입니다.

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

5. 예제 테스트

다음은 RestTemplate 인터셉터 를 테스트하기위한 JUnit 테스트 케이스입니다 .

public class RestTemplateItegrationTest {

    @Autowired
    RestTemplate restTemplate;

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

        ResponseEntity<String> 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 요청 및 응답 서비스 http://httpbin.org **** 를 사용하여 데이터를 게시했습니다. 이 테스트 서비스는 요청 본문과 일부 메타 데이터를 반환합니다.

6. 결론

이 튜토리얼은 인터셉터를 설정하고 RestTemplate 객체에 추가하는 방법에 관한 것 입니다. 이러한 종류의 인터셉터는 들어오는 요청을 필터링, 모니터링 및 제어하는 ​​데에도 사용할 수 있습니다.

RestTemplate 인터셉터 의 일반적인 유스 케이스 는 헤더 수정입니다.이 기사에서 자세히 설명했습니다.

그리고 항상 그렇듯이 Github project 에서 예제 코드를 찾을 수 있습니다 . 이것은 Maven 기반 프로젝트이므로 그대로 가져오고 실행할 수 있어야합니다.

참고

https://www.baeldung.com/spring-rest-template-interceptor

반응형