Interceptor in Spring 5 WebFlux

Viewed 14838

I am using Spring WebFlux in my project. I want to create an interceptor to calculate the time taken by each API. In Spring MVC we have HandlerInterceptor which is not present in spring-boot-starter-webflux. I tried adding spring-boot-starter-web and wrote my interceptor but it didn't work. Here is the code:

@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);

}
...
...

I want to add similar functionality to my application and intercept time taken by each call.

Thanks in advance.

4 Answers

If you want to handle a request when it starts and when it completes, you can use WebFilter.

Try something like this

@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);
        });
    }
}

When request processing starts all defined filters are called. Mono is returned from filter. It indicates when request processing is complete.

Use the following project as dependency as 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>

It provides ReactiveApiInterceptor which is a custom implementation of WebFilter

If required, you can override ReactiveApiInterceptor as well, to add your own custom logic, besides having the default logic, by calling

@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
        });
}
Related