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

时间:2018-05-28 06:00:16

标签: spring-boot spring-webflux

众所周知,在球衣中我们有预匹配滤镜和后匹配滤镜。

我想知道如何在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";
}
}

我可以看到,无论我访问/示例还是/ notexist,都会执行过滤器

其实我喜欢我的过滤器进行后匹配,只为/ example执行。

更具体地说,我希望看到/ example的控制台输出:

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

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

由于

莱昂

1 个答案:

答案 0 :(得分:0)

Spring WebFlux WebFilter类与Jersey中的前/后匹配过滤器不在同一级别。它实际上更接近Servlet过滤器。

WebFilter对处理请求的内容一无所知 - 它可能是一个Controller,一个提供静态资源的处理程序,或者任何其他自定义处理程序。

由于您在此处处于HTTP级别,因此您只需检查请求路径以及响应状态是否为“#34; 404 Not Found&#34;。

由于你的问题没有提供很多关于你在这里尝试实现的内容(业务逻辑?认证?记录?跟踪?任何涉及I / O的操作?),我真的不能说更多关于Reactor运算符的选择。

如果你想要一个仅在资源上运行的过滤器(如泽西资源),则WebFilter不是正确的选择,因为它在较低级别运行(所有HTTP交换) )。我不认为Spring Framework中有基础设施。随意在Spring Framework中打开增强请求(这次提供有关您的用例的足够详细信息)。