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.