一尘不染

如何在webflux中进行匹配后过滤?

spring-boot

众所周知,在运动衫中,我们有匹配前过滤器和匹配后过滤器。

我想知道如何在webflux应用程序中使用WebFilter获得类似的行为。

似乎WebFilter有点像预匹配过滤器,无论是否在@RestController中找到资源,都可以肯定地执行该过滤器。

我的过滤器是这样的(从弹簧执行器的度量过滤器复制):

@Component
@Order(100)
public class AppFilter1 implements WebFilter {

@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {

    return chain.filter(exchange).compose((call) -> filter(exchange, call));
}

private Publisher<Void> filter(ServerWebExchange exchange, Mono<Void> call) {

    System.out.println("Start AppFilter1 in thread:" + Thread.currentThread().getId() + "..........");
    ServerHttpResponse response = exchange.getResponse();
    return call.doOnSuccess((done) -> success(exchange)).doOnError((cause) -> {
        if (response.isCommitted()) {
            error(exchange, cause);
        } else {
            response.beforeCommit(() -> {
                error(exchange, cause);
                return Mono.empty();
            });
        }
    });
}

private void success(ServerWebExchange exchange) {

    System.out.println("End AppFilter1 in thread:" + Thread.currentThread().getId() + "..............");

}

private void error(ServerWebExchange exchange, Throwable cause) {
    System.out.println("End AppFilter1 with Error in thread:" + Thread.currentThread().getId() + "...............");
}

}

添加我的控制器就像:

@RestController
public class ExampleController {

@GetMapping("/example")
public String example() {
    System.out.println("Example in thread:" + Thread.currentThread().getId());
    return "Example";
}
}

我看到的是,无论我访问/ example还是/ notexist,都将确保执行过滤器

实际上,我希望过滤器执行后匹配,仅针对/ example执行。

更具体地说,我想查看/ example的控制台输出:

Start AppFilter1 in thread:....
Example in thread:.....
End AppFilter1 in thread:....

对于/ notexist这样不匹配的资源,根本没有控制台输出。

谢谢

里昂


阅读 1003

收藏
2020-05-30

共1个答案

一尘不染

Spring WebFlux WebFilter类的运行方式与Jersey中的前置/后置匹配过滤器不同。实际上,它更接近Servlet过滤器。

WebFilter没有关于什么是处理请求的线索-它可能是一个控制器,一个处理器提供静态资源,或任何其他自定义处理程序。

由于您处于HTTP级别,因此您只需检查请求路径以及响应状态是否不是“ 404 Not Found”。

由于您的问题并未为您在此处要实现的目标(业务逻辑,身份验证,日志记录,跟踪以及涉及I /
O的任何操作?)提供太多背景知识,因此我无法真正说出更多关于Reactor运算符的选择。

如果您想要只在资源上运行的过滤器(如Jersey
Resources中的内容),那么它WebFilter是不正确的选择,因为它在较低级别上运行(所有HTTP交换)。我认为Spring
Framework中没有用于此目的的基础结构。随时在Spring Framework中打开一个增强请求(这次提供了有关您的用例的足够详细信息)。

2020-05-30