如何在 webflux 中进行匹配后过滤? [英] How to do post-matching filter in webflux?

查看:56
本文介绍了如何在 webflux 中进行匹配后过滤?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

众所周知,在 jersey 中,我们有预匹配过滤器和后匹配过滤器.

As we know, in jersey we have pre-matching filter and post-matching filter.

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

I'm wondering how can I get similar behavior with WebFilter in webflux application.

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

It seems the WebFilter is sort of like a pre-matching filter which will be executed for sure, no matter a resource in @RestController found or not.

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

My filter like this (copied from metrics filter in spring actuator):

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

What I can see is the filter will be executed for sure no matter I access /example or /notexist

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

Actually I'd like my filter to do post-matching, only executed for /example.

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

To be more specific, I'd like to see console output for /example:

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

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

and for a not matched resource like /notexist, there's no console output at all.

谢谢

莱昂

推荐答案

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

The Spring WebFlux WebFilter class does not operate at the same level as the pre/post matching filters in Jersey. It's actually closer to a Servlet filter.

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

The WebFilter has no clue about what is handling the request - it could be a Controller, a handler serving static resources, or any other custom handler.

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

Since you're at the HTTP level here, you can just check for the request path and whether the response status is not "404 Not Found".

由于您的问题没有提供有关您在这里尝试实现的目标的太多背景信息(业务逻辑?身份验证?日志记录?跟踪?任何涉及 I/O 的操作?),我真的不能说更多关于选择的信息反应堆操作员.

Since your question does not provide much background about what you're trying to achieve here (business logic? authentication? logging? tracing? any operation that involves I/O?), I can't really say more about the choice of Reactor operator.

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

If you'd like a filter that only operates on Resources (as in Jersey Resources), then WebFilter is not the right choice as it's operating at a lower level (all HTTP exchanges). I don't think there's infrastructure for that in Spring Framework. Feel free to open an enhancement request in Spring Framework (this time providing enough details about your use case).

这篇关于如何在 webflux 中进行匹配后过滤?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆