湊巧最近這段時間使用Springmvc中的HandlerInterceptor
和ExceptionHandler
,發(fā)現(xiàn)他們使用過程中的一些局限性,并不是所有異常都可以通過ExceptionHandler
捕捉到评甜,以及HandlerInterceptor
和Filter
的區(qū)別撼玄。
我們知道,在java web中蜈漓,原生listener
穆桂,filter
, servlet
執(zhí)行順序為:
Listener------>Filter----->Servlet
而在SpringMVC中,實質(zhì)就是一個DispatchServlet
融虽。
而在Servlet中享完,則是調(diào)用了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());
//執(zhí)行了HandlerInterceptor的preHandle
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
//真正處理請求
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
//執(zhí)行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);
}
所以般又, 調(diào)用順序會變成:
Listener------>Filter----->DispatchServlet ---->HandlerInterceptor.preHandle---->handle---->HandlerInterceptor. postHandle------>ExceptionHandler
所以,在調(diào)用過程中巍佑,HandlerInterceptor是在Filter調(diào)用之后茴迁,而ExceptionHandler異常處理也是在Filter之后,同理可得萤衰,F(xiàn)ilter中的異常是不能被ExceptionHandler處理的堕义。