Spring MVC異常處理機制示例詳解
前言
在Spring MVC中,當一個請求發生異常(Controller丟擲一個異常時),DispatcherServlet 採用委託的方式交給一個處理鏈來處理或者解析這個丟擲的異常,這是在request和Servlet Container之間的一道屏障,所以我們可以在這裡做一些處理工作,如轉換異常,轉換成友好的error page或者http 狀態碼等。
核心介面
這個處理機制在Spring是以HandlerExceptionResolver介面為核心的,該介面只有一個處理方法:
ModelAndView resolveException( HttpServletRequest request,HttpServletResponse response,Object handler,Exception ex);
對於返回值 ModelAndView,有如下約定:
- ModelAndView 指向一個頁面
- 空的ModelAndView,表示異常已經在 HandlerExceptionResolver內部處理完成
- null表示異常未處理,需要繼續執行其它的HandlerExceptionResolver
你可以通過宣告多個HandlerExceptionResolver bean,並實現Ordered介面,來組成一個有順序的HandlerExceptionResolver chain來處理異常。
Spring已經提供了以下幾種實現:
- SimpleMappingExceptionResolver處理邏輯是根據Exception的class name對映成指定的error page。
- DefaultHandlerExceptionResolver 是根據異常的型別轉成http 狀態碼。
- ResponseStatusExceptionResolver 是根據把異常和狀態碼通過@ResponseStatus繫結,當有異常丟擲時,最終給客戶端返回對應的狀態碼。
- ExceptionHandlerExceptionResolver 是處理@ExceptionHandler的解析類,當有異常發生時,交給@ExceptionHandler方法去處理。
處理邏輯
對ExceptionResolver的處理是在DispatcherServlet中進行的
DispatcherServlet有一個屬性,這就表示前邊提到的chain:
/** List of HandlerExceptionResolvers used by this servlet */ private List<HandlerExceptionResolver> handlerExceptionResolvers;
在DispatcherServlet初始化的時候同時對handlerExceptionResolvers進行了初始化
它從ApplicationContext中查詢所有HandlerExceptionResolver bean,然後排序,上邊這就是初始化工作.
在processHandlerException方法完成的對 HandlerExceptionResolver chain的呼叫,返回值不為null,即視作處理完成
// Check registered HandlerExceptionResolvers... ModelAndView exMv = null; for (HandlerExceptionResolver handlerExceptionResolver : this.handlerExceptionResolvers) { exMv = handlerExceptionResolver.resolveException(request,response,handler,ex); if (exMv != null) { break; } }
自定義異常處理器,可以實現HandlerExceptionResolver,也可以繼承AbstractHandlerExceptionResolver類,實現doResolveException方法即可。
這裡重點說下功能最為豐富的ExceptionHandlerExceptionResolver
通過@ExceptionHandler註解的方法,被視為異常處理方法,是通過ExceptionHandlerExceptionResolver來處理。該方法支援的引數型別有:
- Exception
- Request/Response
- Session
- WebRequest or NativeRequest
- java.util.Locale
- java.io.InputStream / java.io.Reader
- java.io.OutputStream / java.io.Writer
- org.springframework.ui.Model
支援的返回值型別有:
- ModelAndView object (Servlet MVC or Portlet MVC).
- org.springframework.ui.Model
- java.util.Map object for exposing a model
- org.springframework.web.servlet.View.
- String value which is interpreted as view name.
- @ResponseBody 可以通過message converters 搭配內容協商來轉換訊息體.
- HttpEntity<?> or ResponseEntity<?>
- void 如果直接通過Response回寫訊息流,則該方法可以返回void
@ExceptionHandler搭配 @ControllerAdvice使用,可作為全域性異常處理器
@ControllerAdvice public class GlobalExceptionController { @ExceptionHandler(CustomGenericException.class) public ModelAndView handleCustomException(CustomGenericException ex) { ModelAndView model = new ModelAndView("error/error"); model.addObject("code”,ex.getErrCode()); model.addObject(“msg”,ex.getErrMsg()); return model; } @ExceptionHandler(Exception.class) public ModelAndView handleAllException(Exception ex) { ModelAndView model = new ModelAndView("error/error"); model.addObject(“msg”,"this is Exception.class"); return model; } }
以上便是Spring MVC中的異常處理邏輯,如有不對的地方,歡迎拍磚。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對我們的支援。