Filtros Spring WebFlux

Filtros Spring WebFlux

1. Visão geral

O uso de filtros é generalizado em aplicativos da Web, pois eles nos permitem modificar uma solicitação ou resposta sem alterar nossos pontos de extremidade.

Neste tutorial rápido, descreveremos possíveis maneiras de implementá-los com o WebFlux Framework.

Como não entraremos em detalhes sobre a estrutura do WebFlux em si, você pode querer verificarthis article para mais detalhes.

2. Dependência do Maven

Antes de tudo, vamos declarar a dependência do WebFlux Maven:


    org.springframework.boot
    spring-boot-starter-webflux

3. Pontos finais

Primeiro precisamos criar alguns pontos de extremidade. Um para cada método: baseado em anotação e funcional.

Vamos começar com o controlador baseado em anotação:

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

Para o terminal funcional, precisamos primeiro criar um manipulador:

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

E também um mapeamento de configuração do roteador:

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

4. Tipos de filtros WebFlux

A estrutura WebFlux fornece dois tipos de filtros:WebFilterseHandlerFilterFunctions.

A principal diferença entre eles é queWebFilter implementations work for all endpoints e HandlerFilterFunction implementations will only work for Router-based ones.

4.1. WebFilter

ImplementaremosWebFilter para adicionar um novo cabeçalho à resposta. Como resultado, todas as respostas devem ter este comportamento:

@Component
public class ExampleWebFilter implements WebFilter {

    @Override
    public Mono filter(ServerWebExchange serverWebExchange,
      WebFilterChain webFilterChain) {

        serverWebExchange.getResponse()
          .getHeaders().add("web-filter", "web-filter-test");
        return webFilterChain.filter(serverWebExchange);
    }
}

4.2. HandlerFilterFunction

Para este, implementamos uma lógica que define o status HTTP paraFORBIDDEN quando o parâmetro “nome” é igual a “teste”.

public class ExampleHandlerFilterFunction
  implements HandlerFilterFunction {

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

5. Teste

No WebFlux Framework, há uma maneira fácil de testar nossos filtros: oWebTestClient. Ele nos permite testar chamadas HTTP para nossos terminais.

Aqui estão exemplos do ponto de extremidade baseado em anotação:

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

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

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

E para o terminal funcional:

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

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

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

6. Conclusão

Cobrimos os dois tipos de filtros WebFlux neste tutorial e demos uma olhada em alguns exemplos de código.

Para obter mais informações sobre o WebFlux Framework, dê uma olhada emdocumentation.

Como sempre, o código-fonte completo dos exemplos pode ser encontradoover on GitHub.