Spring MVC異常處理機制示例詳解
前言
在Spring MVC中,當(dāng)一個請求發(fā)生異常(Controller拋出一個異常時), DispatcherServlet 采用委托的方式交給一個處理鏈來處理或者解析這個拋出的異常,這是在request和Servlet Container之間的一道屏障,所以我們可以在這里做一些處理工作,如轉(zhuǎn)換異常,轉(zhuǎn)換成友好的error page或者h(yuǎn)ttp 狀態(tài)碼等。
核心接口
這個處理機制在Spring是以HandlerExceptionResolver接口為核心的,該接口只有一個處理方法:
ModelAndView resolveException( HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex);
對于返回值 ModelAndView,有如下約定:
- ModelAndView 指向一個頁面
- 空的ModelAndView,表示異常已經(jīng)在 HandlerExceptionResolver內(nèi)部處理完成
- null表示異常未處理,需要繼續(xù)執(zhí)行其它的HandlerExceptionResolver
你可以通過聲明多個HandlerExceptionResolver bean,并實現(xiàn)Ordered接口,來組成一個有順序的HandlerExceptionResolver chain來處理異常。
Spring已經(jīng)提供了以下幾種實現(xiàn):
- SimpleMappingExceptionResolver 處理邏輯是根據(jù)Exception的class name映射成指定的error page。
- DefaultHandlerExceptionResolver 是根據(jù)異常的類型轉(zhuǎn)成http 狀態(tài)碼。
- ResponseStatusExceptionResolver 是根據(jù)把異常和狀態(tài)碼通過@ResponseStatus綁定,當(dāng)有異常拋出時,最終給客戶端返回對應(yīng)的狀態(tài)碼。
- ExceptionHandlerExceptionResolver 是處理@ExceptionHandler的解析類,當(dāng)有異常發(fā)生時,交給@ExceptionHandler方法去處理。
處理邏輯
對ExceptionResolver的處理是在DispatcherServlet中進(jìn)行的
DispatcherServlet有一個屬性,這就表示前邊提到的chain:
/** List of HandlerExceptionResolvers used by this servlet */ private List<HandlerExceptionResolver> handlerExceptionResolvers;
在DispatcherServlet初始化的時候同時對handlerExceptionResolvers進(jìn)行了初始化

它從ApplicationContext中查詢所有HandlerExceptionResolver bean,然后排序,上邊這就是初始化工作.
在processHandlerException方法完成的對 HandlerExceptionResolver chain的調(diào)用,返回值不為null,即視作處理完成
// Check registered HandlerExceptionResolvers...
ModelAndView exMv = null;
for (HandlerExceptionResolver handlerExceptionResolver : this.handlerExceptionResolvers) {
exMv = handlerExceptionResolver.resolveException(request, response, handler, ex);
if (exMv != null) {
break;
}
}
自定義異常處理器,可以實現(xiàn)HandlerExceptionResolver,也可以繼承AbstractHandlerExceptionResolver類,實現(xiàn)doResolveException方法即可。
這里重點說下功能最為豐富的ExceptionHandlerExceptionResolver
通過@ExceptionHandler注解的方法,被視為異常處理方法,是通過ExceptionHandlerExceptionResolver來處理。該方法支持的參數(shù)類型有:
- 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 搭配內(nèi)容協(xié)商來轉(zhuǎn)換消息體.
- 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中的異常處理邏輯,如有不對的地方,歡迎拍磚。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,謝謝大家對腳本之家的支持。
相關(guān)文章
使用JDBC4.0操作XML類型的字段(保存獲取xml數(shù)據(jù))的方法
jdbc4.0最重要的特征是支持xml數(shù)據(jù)類型,接下來通過本文重點給大家介紹如何使用jdbc4.0操作xml類型的字段,對jdbc4.0 xml相關(guān)知識感興趣的朋友一起看下吧2016-08-08
struts2實現(xiàn)文件上傳顯示進(jìn)度條效果
這篇文章主要為大家詳細(xì)介紹了struts2實現(xiàn)文件上傳顯示進(jìn)度條效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-05-05
Java JVM運行時數(shù)據(jù)區(qū)(Run-Time Data Areas)
運行時數(shù)據(jù)區(qū),是java虛擬機定義的在程序執(zhí)行期間使用的各種運行時的數(shù)據(jù)區(qū),通過JVM運行時數(shù)據(jù)區(qū)圖例給大家展示的很詳細(xì),對JVM 運行時數(shù)據(jù)區(qū)相關(guān)知識感興趣的朋友跟隨小編一起看看吧2021-06-06
k8s部署的java服務(wù)添加idea調(diào)試參數(shù)的方法
文章介紹了如何在K8S容器中的Java服務(wù)上進(jìn)行遠(yuǎn)程調(diào)試,包括配置Deployment、Service以及本地IDEA的調(diào)試設(shè)置,感興趣的朋友跟隨小編一起看看吧2025-02-02

