你可以通过使用路由函数生成器上的前、后或过滤方法来过滤处理函数。通过注解,你可以通过使用 @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 上)。 :::