Spring MVC InterceptorHandler用DeferredResult调用了两次
问题内容:
当我使用custom HandlerInterceptor
且我的控制器返回时DeferredResult
,
preHandle
我的自定义拦截器方法在每个请求上调用两次。考虑一个玩具的例子。
我的自定义拦截器:
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 {
}
}
我的Spring Java配置:
@Configuration
@EnableWebMvc
public class ApplicationConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor());
}
}
我的控制器:
@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;
}
}
因此,在每次加载页面时,我都会从preHandle
方法中看到两个输出。但是,如果我修改MyController
以仅返回“空白”模板(而不是DeferredResult
“空白”模板),则preHandle
在每个页面加载中仅看到一个输出。
所以,我的问题是,为什么preHandle
在使用时会被调用两次,DeferredResult
并且有可能避免这种情况?
问题答案:
您需要使用org.springframework.web.servlet.AsyncHandlerInterceptor
:
public interface AsyncHandlerInterceptor extends HandlerInterceptor {
void afterConcurrentHandlingStarted(
HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception;
}
Spring MVC 执行顺序:
preHandle
afterConcurrentHandlingStarted
preHandle
postHandle
afterCompletion