弹簧反应器中的拦截器

时间:2017-11-03 08:55:20

标签: spring spring-mvc spring-webflux

我在我的项目中使用spring boot 2.0.0.M5,内部使用spring 5.0.0.RELEASE。我想创建一个拦截器来计算每个api所用的时间。在spring< = 4.X中,我们有HandlerInterceptor,它不存在于spring-boot-starter-webflux中。我尝试添加spring-boot-starter-web并编写了我的拦截器,但它没有用。

@Component
public class TimeInterceptor implements HandlerInterceptor {

public static Logger logger = Logger.getLogger(TimeInterceptor.class);

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    long startTime = System.currentTimeMillis();
    request.setAttribute("startTime", startTime);
    return true;
}

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    long totaltime = System.currentTimeMillis() - (long) request.getAttribute("startTime");
    request.setAttribute("totaltime", totaltime);
    logger.info("Logging total time" + totaltime);

}
...
...

我希望在我的spring reactor应用程序中添加类似的虚构性并拦截每次调用所花费的时间。

提前致谢。

4 个答案:

答案 0 :(得分:2)

Spring WebFlux中没有HandlerInterceptor的概念,但您可以使用自己的WebFilter代替。

您所描述的功能听起来很像Actuator和Micrometer提供的指标支持。如果您想尝试一下:

  1. 将执行器依赖项添加到项目中
  2. 公开the relevant endpoints(此处为metrics
  3. 转到"/actuator/metrics并选择服务器HTTP请求的指标(请参阅the reference documentation)。
  4. Micrometer提供更多方法并帮助您正确地衡量指标,例如:在测量时间时考虑GC暂停,提供直方图/百分位数/ ......等等。

    注意:向应用程序添加spring-boot-starter-web会将其转换为Spring MVC应用程序。

答案 1 :(得分:0)

如果您想在请求启动和完成时处理该请求,则可以使用WebFilter

尝试这样的事情

@Component
public class CustomWebFilter implements WebFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        long startTime = System.currentTimeMillis();
        return chain.filter(exchange).doFinally(signalType -> {
            long totalTime = System.currentTimeMillis() - startTime;
            exchange.getAttributes().put("totalTime", totalTime);
            System.out.println(totalTime);
        });
    }
}

启动请求处理时,将调用所有定义的过滤器。 Mono从过滤器返回。它指示请求处理何时完成。

答案 2 :(得分:0)

使用如下项目作为依赖为jar/ant/maven/gradle

https://github.com/TurquoiseSpace/spring-webflux-http-interceptor

<dependency>
    <groupId>com.github.TurquoiseSpace</groupId>
    <artifactId>spring-webflux-http-interceptor</artifactId>
    <version>0.0.7</version>
</dependency>

它提供了 ReactiveApiInterceptor,它是 WebFilter

的自定义实现

答案 3 :(得分:0)

如果需要,您也可以覆盖 ReactiveApiInterceptor 以添加您自己的自定义逻辑,除了具有默认逻辑外,调用

@Override
public Mono<Void> filter(ServerWebExchange serverWebExchange, WebFilterChain webFilterChain) {
    // Your custom implementation, when api is hit and the request lands
    super.filter(serverWebExchange, webFilterChain)
        .doFinally(signalType -> {
            // Your custom implementation, when request-response exchange gets completed
        });
}