본문 바로가기
Baeldung번역&공부/Spring-Reactive

Spring WebClient와 Filter(Spring WebClient Filters)

by ms727 2025. 3. 6.

원본 글: https://www.baeldung.com/spring-webclient-filters

이 글은 WebClient에서 fitler를 다루는 방법에 대해 이야기합니다.

1. Request Filters

filter는 요청과 응답을 가로채서 추가,수정할 수 있는 기능입니다. 필터는 모든 요청과 응답에 대해 한 곳에 모여지므로 후처리나 전처리하기에 적합합니다. 요청을 모니터링하거나 수정, 로그 작성, 인증까지 가능합니다.

Spring Reactive에서 필터는 함수형 인터페이스 ExchangeFilterFunction의 인스턴스입니다. 필터 함수에는 두 개의 매개변수가 있습니다. 수정할 ClientRequest와 다음 ExchangeFilterFunction입니다.

일반적인 구성 예시입니다.

ExchangeFilterFunction filterFunction = (clientRequest, nextFilter) -> {
    LOG.info("WebClient fitler executed");
    return nextFilter.exchange(clientRequest);
};

2. WebClient Filtering

요청 필터를 구현한 뒤에는 WebClient 인스턴스에 추기해줘야하는데, 이는 WebClient생성시에만 가능합니다.

WebClient를 기본적인 형태로 선언하는 방법은 다음과 같습니다.

WebClient webClient = WebClient.create();

다음은 filter를 추가하는 방법입니다.

WebClient webClient = WebClient.builder()
  .filter(filterFunction)
  .build();

이걸 토대로 다음과 같은 예시를 작성할 수 있습니다.

@Test
void filer_basic_test() {
    ExchangeFilterFunction filterFunction = (clientRequest, nextFilter) -> {
        System.out.println("WebClient fitler executed");
        return nextFilter.exchange(clientRequest);
    };

    WebClient webClient = WebClient.builder().filter(filterFunction).build();

    webClient.get().uri("https://www.google.com").exchange().block();
}

요철을 보낼대마다 "WebClient fitler executed" 이 구문이 찍히는걸 확인할 수 있습니다.

3. A Custom Filter

HTTP method가 GET일 때 카운팅하는 커스텀한 필터를 제작해봅니다.

@Test
void count_filter_test() {
    AtomicInteger count = new AtomicInteger(0);
    ExchangeFilterFunction filterFunction = (clientRequest, nextFilter) -> {
        HttpMethod method = clientRequest.method();
    if(method == HttpMethod.GET) {
        count.incrementAndGet();
    }

    return nextFilter.exchange(clientRequest);
    };

    WebClient webClient = WebClient.builder().filter(filterFunction).build();
    for(int i =0; i< 50; ++i) {
    webClient.get().uri("https://www.google.com").exchange().block();
    }
    System.out.println("count: " + count.get());
}

count값은 50이 찍힐겁니다.

만약에 api 버전이 바뀌어서 일괄로 url에 있는 버전정보를 바꿔야한다면 어떻게 해야할까요? 필터에서 처리가 가능합니다.

ExchangeFilterFunction urlModifyingFilter = (clientRequest, nextFilter) -> {
    // 1. 기존 요청 URL 가져오기
    String oldUrl = clientRequest.url().toString();

    // 2. 새로운 URL 생성 (버전 정보 추가)
    URI newUrl = URI.create(oldUrl + "/" + version);

    // 3. 기존 요청을 기반으로 URL이 수정된 새 요청 생성
    ClientRequest filteredRequest = ClientRequest.from(clientRequest)
      .url(newUrl)
      .build();

    // 4. 수정된 요청을 다음 필터에 전달하여 실행
    return nextFilter.exchange(filteredRequest);
};

다음은 필터에 로그성 정보를 남기는 코드입니다.

@Test
void log_filter_test() {
    ExchangeFilterFunction loggingFilter = (clientRequest, nextFilter) -> {
        System.out.println("Sending request " + clientRequest.method() + " " + clientRequest.url());
        return nextFilter.exchange(clientRequest);
    };

    WebClient webClient = WebClient.builder().filter(loggingFilter).build();

    webClient.get().uri("https://www.google.com").exchange().block();
}

4. A Standard Filter

마지막으로 요청 필터의 기본적인 사용사례 중 하나인 기본 인증을 살펴보겠습니다.

ExchangeFilterFunctions 헬퍼 클래스에서는 basicAuthentication() 이라는 함수를 제공하여 기본적인 인증을 진행할 수 있게합니다.

WebClient webClient = WebClient.builder().filter(ExchangeFilterFunctions.basicAuthentication("minseok", "123"))
                .build();

5. 결론

이 글에서는 WebClient에 filter를 적용하는 방법에 대해 학습하였습니다.

예제코드