1.SpringMVC 異常的處理流程
????????異常分為編譯時異常和運行時異常,編譯時異常我們 try-cache 進行捕獲,捕獲后自行處理,而運行時異常是不 可預期的,就需要規范編碼來避免,在SpringMVC 中,不管是編譯異常還是運行時異常,都可以最終由 SpringMVC提供的異常處理器進行統一處理,這樣就避免了隨時隨地捕獲處理的繁瑣性。
????????SpringMVC 處理異常的思路是,一路向上拋,都拋給前端控制器 DispatcherServlet ,DispatcherServlet 在調 用異常處理器ExceptionResolver進行處理,如下圖:
?2.SpringMVC 的異常處理方式
?SpringMVC 提供了以下三種處理異常的方式:
- 簡單異常處理器:使用SpringMVC 內置的異常處理器處理SimpleMappingExceptionResolver;
- 自定義異常處理器:實現HandlerExceptionResolver接口,自定義異常進行處理;
- 注解方式:使用@ControllerAdvice + @ExceptionHandler 來處理
? ? ? ? 1.使用SimpleMappingExceptionResolver處理一些簡單異常,配置開啟SimpleMappingExceptionResolver, 并指定異常捕獲后的處理動作,當發生了異常后,會被 SimpleMappingExceptionResolver 處理,跳轉到我們 配置的錯誤頁面error.html給用戶進行友好展示?
<!--配置簡單異常處理器-->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
?<!-- 異常捕獲后動作:展示視圖 -->
?<property name="defaultErrorView" value="/error.html"/>
</bean
?可以在配置SimpleMappingExceptionResolver時,指定一些參數,例如:異常的類型
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
?<property name="defaultErrorView" value="/error.html"/>
?<property name="exceptionMappings">
?<props>
?<!-- 配置異常類型對應的展示視圖 -->
?<prop key="java.lang.RuntimeException">/error.html</prop>
?<prop key="java.io.FileNotFoundException">/io.html</prop>
?</props>
?</property>
</bean>?
注解方式配置簡單映射異常處理器?
@Bean
public SimpleMappingExceptionResolver simpleMappingExceptionResolver(){//創建SimpleMappingExceptionResolverSimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();//設置默認錯誤展示視圖resolver.setDefaultErrorView("/error.html");//定義Properties設置特殊異常對應的映射視圖Properties properties = new Properties();properties.setProperty("java.lang.RuntimeException","/error.html");properties.setProperty("java.io.FileNotFoundException","/io.html");resolver.setExceptionMappings(properties);return resolver;
}
?2.自定義異常處理器,實現HandlerExceptionResolver接口自定義異常處理器,可以完成異常邏輯的處理
public class MyHandlerExceptionResolver implements HandlerExceptionResolver {@Override//參數Object是當前目標方法處理器對象HandlerMethodpublic ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {ModelAndView modelAndView = new ModelAndView();modelAndView.setViewName("/error.html");return modelAndView;}
}
交給Spring管理異常處理器
<bean class="com.fly.exception.MyHandlerExceptionResolver"></bean>
自定義異常處理器,返回Json格式字符串信息
@Component
public class MyHandlerExceptionResolver implements HandlerExceptionResolver {@Overridepublic ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {//編寫要返回的json格式的字符串String jsonStr = "{\"code\":0,\"message\":\"error\",\"data\":\"\"}";try {httpServletResponse.getWriter().write(jsonStr);} catch (IOException e1) {e1.printStackTrace();}return null;}
}
?3.使用注解 @ControllerAdvice + @ExceptionHandler 配置異常,@ControllerAdvice 注解本質是一個 @Component,也會被掃描到,與此同時,具備AOP功能,默認情況下對所有的Controller都進行攔截操作, 攔截后干什么呢?就需要在結合@ExceptionHandler、@InitBinder、@ModelAttribute 注解一起使用了,此 處我們講解的是異常,所以是@ControllerAdvice + @ExceptionHandler的組合形式
編寫全局異常處理器類,使用@ControllerAdvice標注,且@ExceptionHandler指定異常類型
@ControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(RuntimeException.class)public ModelAndView runtimeHandleException(RuntimeException e){System.out.println("全局異常處理器執行...."+e);ModelAndView modelAndView = new ModelAndView("/error.html");return modelAndView;}@ExceptionHandler(IOException.class)@ResponseBodypublic ResultInfo ioHandleException(IOException e){//模擬一個ResultInfoResultInfo resultInfo = new ResultInfo(0,"IOException",null);return resultInfo;}
}
如果全局異常處理器響應的數據都是Json格式的字符串的話,可以使用@RestControllerAdvice替代 @ControllerAdvice 和 @ResponseBody
@RestControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(RuntimeException.class)public ResultInfo runtimeHandleException(RuntimeException e){//模擬一個ResultInfoResultInfo resultInfo = new ResultInfo(0,"RuntimeException",null);return resultInfo;}@ExceptionHandler(IOException.class)public ResultInfo ioHandleException(IOException e){//模擬一個ResultInfoResultInfo resultInfo = new ResultInfo(0,"IOException",null);return resultInfo;}
}
3.SpringMVC 常用的異常解析器
接口/類 | 說明 |
HandlerExceptionResolver | 異常處理器類的頂級接口,實現了該接口的類都會作為異常處理器類 |
MyHandlerExceptionResolver | 自定義的處理器類,實現了HandlerExceptionResolver接口 |
HandlerExceptionResolverComposite | 異常解析器混合器,內部存在集合存儲多種異常解析器 |
SimpleMappingExceptionResolver | 簡單映射異常處理器,可以配置異常與對應的錯誤視圖 |
ExceptionHandlerExceptionResolver | 異常處理器異常解析器,默認會被注冊到Spring容器中,@ExceptionHandler方式 異常處理就是該解析器解析的 |
DefaultHandlerExceptionResolver | 默認處理器異常解析器,所有異常處理器都不匹配時,最后執行的異常處理器 |
ResponseStatusExceptionResolver | 響應狀態異常解析器,結合使用@ResponseStatus標注的異常使用 |