你可以通过使用路由函数生成器上的前、后或过滤方法来过滤处理函数。通过注解,你可以通过使用 @ControllerAdvice、ServletFilter或两者实现类似的功能。该过滤器将应用于由构建器构建的所有路由。这意味着在嵌套路由中定义的过滤器并不适用于 「顶层」路由。例如,考虑下面的例子:
RouterFunction<ServerResponse> route = route().path("/person", b1 -> b1.nest(accept(APPLICATION_JSON), b2 -> b2.GET("/{id}", handler::getPerson).GET(handler::listPeople)// 添加自定义请求头的 before 过滤器只适用于两个 GET 路由。.before(request -> ServerRequest.from(request).header("X-RequestHeader", "Value").build())).POST("/person", handler::createPerson))// 记录响应的后置过滤器适用于所有路由,包括嵌套的路由。.after((request, response) -> logResponse(response)).build();
路由器构建器上的过滤方法接收一个 HandlerFilterFunction:一个接收 ServerRequest 和 HandlerFunction 并返回 ServerResponse 的函数。处理程序函数参数代表链中的下一个元素。这通常是被路由到的处理程序,但如果应用多个过滤器,它也可以是另一个过滤器。
现在我们可以给我们的路由添加一个简单的安全过滤器,假设我们有一个 SecurityManager,可以确定某个特定路径是否被允许。下面的例子显示了如何做到这一点:
SecurityManager securityManager = ...RouterFunction<ServerResponse> route = route().path("/person", b1 -> b1.nest(accept(APPLICATION_JSON), b2 -> b2.GET("/{id}", handler::getPerson).GET(handler::listPeople)).POST("/person", handler::createPerson)).filter((request, next) -> {if (securityManager.allowAccessTo(request.path())) {return next.handle(request);}else {return ServerResponse.status(UNAUTHORIZED).build();}}).build();
前面的例子表明,调用 next.handle(ServerRequest) 是可选的。我们只在允许访问时让处理函数运行。
除了在路由器函数生成器上使用过滤器方法,还可以通过 RouterFunction.filter(HandlerFilterFunction)将过滤器应用于现有的路由器函数。
:::info 对功能端点的 CORS 支持是通过一个专门的 CorsFilter 提供的(原文的跳转链接失效了,所以不太确定是如何配置的,难道是和 SpringMVC 提供的是同一个?因为 WebMvc.fn 也运行在 DispatcherServlet 上)。 :::
