在開發中,不管是dao層、service層還是controller層,都有可能拋出異常,在springmvc中,能將所有類型的異常處理從各處理過程解耦出來,既保證了相關處理過程的功能較單一, 也實現了異常信息的統一處理和維護 。
springmvc的異常處理思路
系統的dao、service、controller出現異常都通過throws Exception向上拋出,最后由springmvc前端控制器交由異常處理器進行異常處理。springmvc提供全局異常處理器(一個系統只有一個異常處理器)進行統一異常處理。
Spring/SpringMVC常見的統一異常處方式:
1) 使用Spring MVC提供的簡單異常處理器SimpleMappingExceptionResolver,處理器實現HandlerExceptionResolver 接口,全局異常處理器需要實現該接口
SimpleMappingExceptionResolver,就是通過簡單的映射關系來決定由哪個視圖,來處理當前的錯誤信息。SimpleMappingExceptionResolver提供通過異常類型exceptionMappings,來進行異常與視圖之間的映射關系,提供在發生異常時,通過statusCodes來映射異常返回的視圖名稱和對應的HttpServletResponse的返回碼。而且可以通過defaultErrorView和defaultErrorCode來指定默認值,defaultErrorView表示當沒有在exceptionMappings里面找到對應的異常類型時,就返回defaultErrorView定義的視圖,defaultErrorCode表示在發生異常時,當沒有在視圖與返回碼的映射關系statusCodes里面找到對應的映射時,默認返回的返回碼。
在使用SimpleMappingExceptionResolver時,當發生異常的時候,SimpleMappingExceptionResolver將會把當前的異常對象放到自身屬性exceptionAttribute中,當沒有指定exceptionAttribute時,exceptionAttribute就是用默認值exception
首先得在webApplicationContext.xml文件中配置該處理器:
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <!--默認的異常處理頁面--> <property name="defaultErrorView" value="user/error"/> //錯誤頁面的路徑:如果配置modelView.addView("/WEB-INF/views"),就是相對路徑 <!--異常處理頁面用來獲取異常信息的變量名,默認為exception--> <property name="exceptionAttribute" value="ex"/> <!--需要特殊處理的異常信息--> <property name="exceptionMappings"> <props> <prop key="com.smart.exception.CustomException">user/custom_error</prop> </props> </property>
<property name="statusCodes"> <!-- 定義在發生異常時視圖跟返回碼的對應關系 -->
<props>
<prop key="number">500</prop> <!-- 表示在發生NumberFormatException時返回視圖number,
然后這里定義發生異常時視圖number對應的HttpServletResponse的返回碼是500 -->
<prop key="null">503</prop>
</props>
</property>
</bean>
最重要的是要配置特殊處理的異常,自定義一個CustomException
package com.smart.exception; /** * 自定義異常 * **/ public class CustomException extends Exception{ private String message; public CustomException(String message){ super(message); this.message=message; } @Override public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
2) 實現Spring的異常處理接口HandlerExceptionResolver 自定義全局異常處理器
全局異常處理器處理思路
- 解析出異常類型
- 如果該異常類型是系統自定義的異常,直接取出異常信息,在錯誤頁面展示
- 如果該異常類型不是系統自定義的異常,構造一個自定義的異常類型
springmvc提供一個HandlerExceptionResolver接口,自定義全局異常處理器必須要實現這個接口
public class CustomExceptionHandler implements HandlerExceptionResolver { @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { ModelAndView modelAndView = new ModelAndView(); if(ex instanceof CustomException){ CustomException exception=(CustomException)ex; modelAndView.addObject("message",exception.getMessage()); modelAndView.setViewName("user/custom_error"); return modelAndView; }else{ modelAndView.addObject("message",ex.getMessage()); modelAndView.setViewName("user/error"); return modelAndView; } } }
在springmvc.xml中配置這個自定義的異常處理器:
<!-- 自定義的全局異常處理器 只要實現HandlerExceptionResolver接口就是全局異常處理器--> <bean class="com.smart.CustomExceptionResolver"></bean>
3) 使用@ExceptionHandler注解實現異常處理
處理局部異常(Controller內)
@ExceptionHandler public ModelAndView exceptionHandler(Exception ex){ ModelAndView mv = new ModelAndView("error"); mv.addObject("exception", ex); System.out.println("in testExceptionHandler"); return mv; } @RequestMapping("/error") public String error(){ int i = 5/0; return "hello"; }
4) 定義一個類並配上注解@ControllerAdvice。然后再該類中定義處理異常的方法並使用注解@ExceptionHandler
處理全局異常(所有Controller)
//全局異常處理,捕獲所有Controller中拋出的異常
@ControllerAdvice public class testControllerAdvice {
//自定義異常 @ExceptionHandler(CustomException.class) public ModelAndView exceptionHandler(Exception ex){ ModelAndView mv = new ModelAndView("error"); mv.addObject("exception", ex); System.out.println("in testControllerAdvice"); return mv; }
@ExceptionHandler(Exception.class)
@ResponseBody
public Object exceptionHandler(Exception e){
,,,,
} }
參考:
https://blog.csdn.net/eson_15/article/details/51731567