1. 개요

필터는 엔드포인트를 변경하지 않고 요청이나 응답을 수정할 수 있는 방법을 제공하므로 웹 애플리케이션에서 필터 사용이 널리 사용됩니다.

이 빠른 사용방법(예제)에서는 WebFlux Framework로 구현하는 가능한 방법을 설명합니다.

WebFlux 프레임워크 자체에 대한 자세한 내용은 다루지 않으므로 자세한 내용은 이 기사  를 참조하십시오.

2. 메이븐 의존성

우선 WebFlux Maven 의존성을 선언해 보겠습니다.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

3. 종점

먼저 일부 Endpoints을 만들어야 합니다. 각 방법에 대해 하나씩: 어노테이션 기반 및 기능 기반.

어노테이션 기반 컨트롤러부터 시작하겠습니다.

@GetMapping(path = "/users/{name}")
public Mono<String> getName(@PathVariable String name) {
    return Mono.just(name);
}

기능적 Endpoints의 경우 먼저 처리기를 만들어야 합니다.

@Component
public class PlayerHandler {
    public Mono<ServerResponse> getName(ServerRequest request) {
        Mono<String> name = Mono.just(request.pathVariable("name"));
        return ok().body(name, String.class);
    }
}

또한 라우터 구성 매핑:

@Bean
public RouterFunction<ServerResponse> route(PlayerHandler playerHandler) {
    return RouterFunctions
      .route(GET("/players/{name}"), playerHandler::getName)
      .filter(new ExampleHandlerFilterFunction());
}

4. WebFlux 필터의 종류

WebFlux 프레임워크는 WebFilterHandlerFilterFunctions 두 가지 유형의 필터를 제공합니다 .

주요 차이점은 WebFilter 구현은 모든 Endpoints에서 작동 하고 HandlerFilterFunction  구현은 라우터 기반 구현에서만 작동한다는 것입니다.  

4.1. 웹필터

응답에 새 헤더를 추가하기 위해 WebFilter 를 구현합니다 . 결과적으로 모든 응답에는 다음과 같은 동작이 있어야 합니다.

@Component
public class ExampleWebFilter implements WebFilter {
 
    @Override
    public Mono<Void> filter(ServerWebExchange serverWebExchange, 
      WebFilterChain webFilterChain) {
        
        serverWebExchange.getResponse()
          .getHeaders().add("web-filter", "web-filter-test");
        return webFilterChain.filter(serverWebExchange);
    }
}

4.2. HandlerFilterFunction

이를 위해 "name" 매개변수가 "test"와 같을 때 HTTP 상태를 FORBIDDEN 으로 설정하는 논리를 구현합니다.

public class ExampleHandlerFilterFunction 
  implements HandlerFilterFunction<ServerResponse, ServerResponse> {
 
    @Override
    public Mono<ServerResponse> filter(ServerRequest serverRequest,
      HandlerFunction<ServerResponse> handlerFunction) {
        if (serverRequest.pathVariable("name").equalsIgnoreCase("test")) {
            return ServerResponse.status(FORBIDDEN).build();
        }
        return handlerFunction.handle(serverRequest);
    }
}

5. 테스트

WebFlux Framework에는 필터를 테스트하는 쉬운 방법인 WebTestClient 가 있습니다. 엔드포인트에 대한 HTTP 호출을 테스트할 수 있습니다.

어노테이션 기반 Endpoints의 예는 다음과 같습니다.

@Test
public void whenUserNameIsBaeldung_thenWebFilterIsApplied() {
    EntityExchangeResult<String> result = webTestClient.get()
      .uri("/users/baeldung")
      .exchange()
      .expectStatus().isOk()
      .expectBody(String.class)
      .returnResult();

    assertEquals(result.getResponseBody(), "baeldung");
    assertEquals(
      result.getResponseHeaders().getFirst("web-filter"), 
      "web-filter-test");
}

@Test
public void whenUserNameIsTest_thenHandlerFilterFunctionIsNotApplied() {
    webTestClient.get().uri("/users/test")
      .exchange()
      .expectStatus().isOk();
}

그리고 기능적 엔드포인트의 경우:

@Test
public void whenPlayerNameIsBaeldung_thenWebFilterIsApplied() {
    EntityExchangeResult<String> result = webTestClient.get()
      .uri("/players/baeldung")
      .exchange()
      .expectStatus().isOk()
      .expectBody(String.class)
      .returnResult();

    assertEquals(result.getResponseBody(), "baeldung");
    assertEquals(
      result.getResponseHeaders().getFirst("web-filter"),
      "web-filter-test");
} 

@Test 
public void whenPlayerNameIsTest_thenHandlerFilterFunctionIsApplied() {
    webTestClient.get().uri("/players/test")
      .exchange()
      .expectStatus().isForbidden(); 
}

6. 결론

이 사용방법(예제)에서는 두 가지 유형의 WebFlux 필터를 모두 다루었고 몇 가지 코드 예제를 살펴보았습니다.

WebFlux Framework에 대한 자세한 내용은 설명서 를 참조하십시오 .

항상 그렇듯이 예제의 전체 소스 코드는 GitHub 에서 찾을 수 있습니다 .

Generic footer banner