When I am using custom HandlerInterceptor and my controller returns DeferredResult, the  preHandle method of my custom interceptor called twice on each request. Consider a toy example.
My custom interceptor:
public class MyInterceptor implements HandlerInterceptor {
    static int i = 0;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println(i++);
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    }
}
My Spring Java configuration:
@Configuration
@EnableWebMvc
public class ApplicationConfiguration extends WebMvcConfigurerAdapter {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor());
    }
}
My Controller:
@Controller
public class MyController {
    @RequestMapping(value = "/test", method = RequestMethod.GET)
    public DeferredResult<String> test() {
        DeferredResult<String> df = new DeferredResult<String>();
        df.setResult("blank");
        return df;
    }
}
So, on each page load I see two outputs from preHandle method. However, if I modify MyController in order to return just "blank" template (instead of DeferredResult with "blank" template), I see just one output from preHandle on each page load. 
So, my question is why preHandle called twice when I use DeferredResult and is it possible to avoid this?
You need to use org.springframework.web.servlet.AsyncHandlerInterceptor:
public interface AsyncHandlerInterceptor extends HandlerInterceptor {
    void afterConcurrentHandlingStarted(
            HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception;
}
Spring MVC execute sequence:
preHandle
afterConcurrentHandlingStarted
preHandle
postHandle
afterCompletion
                        The difference between the two invocations can be seen by examining the value of request.getDispatcherType().
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With