如何在 webflux 中做 post-匹配过滤器?

How to do post-matching filter in webflux?

众所周知,在球衣中我们有预匹配过滤器和 post-匹配过滤器。

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

看起来 WebFilter 有点像预匹配过滤器,无论是否找到 @RestController 中的资源,它都会被执行。

我的过滤器是这样的(从 spring 执行器中的指标过滤器复制):

@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,过滤器都会被执行

实际上我希望我的过滤器进行 post 匹配,只针对 /example 执行。

更具体地说,我想查看 /example:

的控制台输出
Start AppFilter1 in thread:....
Example in thread:.....
End AppFilter1 in thread:....

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

谢谢

里昂

Spring WebFlux WebFilter class 与 Jersey 中的 pre/post 匹配过滤器的操作级别不同。它实际上更接近于 Servlet 过滤器。

WebFilter 不知道什么在处理请求 - 它可能是控制器、提供静态资源的处理程序或任何其他自定义处理程序。

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

由于你的问题没有提供太多关于你在这里试图实现的目标的背景(业务逻辑?身份验证?日志记录?跟踪?任何涉及 I/O 的操作?),我真的不能说更多关于 Reactor 运算符的选择。

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