在WebFlux中处理端点注释的控制器拦截器

时间:2018-09-07 09:55:04

标签: spring spring-webflux

我的团队正在将我们的Spring MVC扩展迁移到WebFlux。

我们有一项功能,可让我们的客户自定义控制器方法的指标。为此,我们创建了由HandlerInterceptorAdapter处理的注释。

问题是我在Spring WebFlux中看不到任何等效的东西。我无法使用WebFilter,因为Spring尚不知道将调用哪个端点。我该如何实施?

我发现最接近的解决方法是使用RequestMappingHandlerMapping并以某种方式构建Map<String(path), HandlerMethod>的映射,但是在我看来,这很麻烦且容易出错。

有没有更好的方法来解决这个问题?

编辑:

像这样

public class MeteredHandlerInterceptor extends HandlerInterceptorAdapter {

public MeteredHandlerInterceptor() {
}

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    // I save start time of method
    return true;
}

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    // I read endpoint method from the HandlerMethod, I apply any customisation by our custom @MeteredEndpoint annotation (for example custom name) and I save it in MeterRegistry
}
}

我还没有编码变通方法,因为我不想花时间在上面,但是我看到我可以获得HandlerMethod的路径,但是我不确定是否会收到相同的{{1 }},就像我通常在调用控制器时一样。

1 个答案:

答案 0 :(得分:0)

也许有点晚了,但它仍然对某人有用...

我还没有找到一种简单的方法来做到这一点,我能创建的最好的方法是一个 HandlerAdapter bean,它以以下方式拦截处理:

@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public HandlerAdapter handlerAdapter(RequestMappingHandlerAdapter requestMappingHandlerAdapter) {
    return new HandlerAdapter() {

        @Override
        public boolean supports(Object handler) {
            return handler instanceof HandlerMethod;
        }

        @Override
        public Mono<HandlerResult> handle(ServerWebExchange exchange, Object handler) {
            // your stuff here...
            // e.g. ((HandlerMethod) handler).getMethod().getAnnotations()...
            return requestMappingHandlerAdapter.handle(exchange, handler);
        }
    };
}

这个想法是这个适配器用于所有 HandlerMethod 处理程序(那些是通过从 @Controllers 收集带注释的方法创建的)并将处理委托给 RequestMappingHandlerAdapter(这将在正常情况下直接用于 HandlerMethod 处理程序,注意这里的 @Order 注释)。

关键是您可以将代码放在调用句柄方法之前/之后,并且您知道此时正在调用的方法。