對於一般的MVC項目,大量的異常須要咱們去處理,如此一來,咱們的 Controller 層就不得不進行 try-catch Service 層的異常,這樣一來,Controller層每一個方法體都須要寫一些模板化的try-catch代碼,很是難看且冗餘,還很差維護。git
正好這裏涉及到兩個annotation類: * @ControllerAdvice 全局異常處理類,再也不須要每一個Controller裏一必定義 * @ExceptionHandler 定義針對每種類型的Exception 固然啦,若是你在業務中已經try catch啦,那就別期望被處理了,你本身都處理了 別人固然不操心了
全局處理類:github
@ControllerAdvice @ResponseBody public class GlobalExceptionHandler { @Autowired private AppResultManager res;//返回結果包裝類 /** * 參數校驗失敗Handler, 如使用 org.springframework.util.Assert 類校驗失敗的處理 * * @param request HttpServletRequest * @param exception catch ConstraintViolationException */ @ExceptionHandler(value = IllegalArgumentException.class) public String assertFailHandler(HttpServletRequest request, IllegalArgumentException exception) { return res.error(exception.getMessage()); } //...省略其餘方法 /** * 全部異常報錯 Handler, 兜底 * * @param request HttpServletRequest * @param exception Exception * @throws Exception 錯誤 */ @ExceptionHandler(value = Exception.class) public String allExceptionHandler(HttpServletRequest request, Exception exception) { exception.printStackTrace(); return res.error(exception.toString()); } }
測試代碼:spring
@RestController @RequestMapping(value = "/helloWorld") public class HelloWorldController { @Autowired private AppResultManager res; @RequestMapping(value = "/test",method = RequestMethod.GET) public String testException(String userName, String callback) { Assert.notNull(userName, "userName can't found"); return res.success(userName, callback); } }
瀏覽器訪問:瀏覽器
http://localhost:8080/helloWorld/test
優勢:將 Controller 層的異常和數據校驗的異常進行統一處理,減小模板代碼,減小編碼量,提高擴展性和可維護性。 缺點:只能處理 Controller 層未捕獲(往外拋)的異常,對於 Interceptor(攔截器)層的異常,Spring 框架層的異常,就無能爲力了。app
gitHub地址: https://github.com/Grit-tan/globalExceptionDemo框架