凑巧最近这段时间使用Springmvc中的HandlerInterceptor
和ExceptionHandler
,发现他们使用过程中的一些局限性,并不是所有异常都可以通过ExceptionHandler
捕捉到,以及HandlerInterceptor
和Filter
的区别。
我们知道,在java web中,原生listener
,filter
, servlet
执行顺序为:
Listener------>Filter----->Servlet
而在SpringMVC中,实质就是一个DispatchServlet
。
而在Servlet中,则是调用了HandlerInterceptor
的各个方法,和最后ExceptionHandler
处理。
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
try {
//获取HandleMapping
mappedHandler = getHandler(processedRequest);
//获取HandlerAdapter
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
//执行了HandlerInterceptor的preHandle
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
//真正处理请求
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
//执行plugins的postHandle
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
catch (Exception ex) {
//如果有异常
dispatchException = ex;
}
catch (Throwable err) {
dispatchException = new NestedServletException("Handler dispatch failed", err);
}
//真正处理异常ExceptionHandler生效的位置
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
所以, 调用顺序会变成:
Listener------>Filter----->DispatchServlet ---->HandlerInterceptor.preHandle---->handle---->HandlerInterceptor. postHandle------>ExceptionHandler
所以,在调用过程中,HandlerInterceptor是在Filter调用之后,而ExceptionHandler异常处理也是在Filter之后,同理可得,Filter中的异常是不能被ExceptionHandler处理的。
网友评论