前面介紹了Spring Boot 如何整合定時任務已經Spring Boot 如何創建異步任務和定時任務。不清楚的朋友可以看看之前的文章:《Spring Boot 入門系列文章》
接下來主要講解如何在SpringBoot應用中使用統一異常處理。如何實現對異常數據與正常的業務數據統一以json形式返回?
為什么要統一異常處理
當前我們項目架構基本上都是前后端分離的模式,采用Restful接口形式協議開發,前台不管任何業務邏輯,只是接受現實數據。但是如果后台發生異常像數據庫異常、權限問題、Redis緩存異常、業務處理錯誤等各種異常時,前端通常會顯示一個非常難看的錯誤頁面。這對於用戶來說非常不友好,也影響業務的正常進行。所以我們需要對各種系統異常進行統一處理,然后返回我們想要的結果。
如何實現
Spring Boot 實現統一異常處理的方法主要有以下兩種:
第一種:使用@ControllerAdvice和@ExceptionHandler注解
第二種:使用ErrorController類來實現。
使用ErrorController的方式比較簡單,這里就不介紹了。今天主要就講講如何使用@ControllerAdvice和@ExceptionHandler注解的方式實現統一異常處理。
1.統一異常處理類
package com.weiz.exception; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.servlet.ModelAndView; import com.weiz.utils.JSONResult; @ControllerAdvice public class GlobalExceptionHandler { public static final String ERROR_VIEW = "error"; @ExceptionHandler(value = Exception.class) public Object errorHandler(HttpServletRequest reqest, HttpServletResponse response, Exception e) throws Exception { e.printStackTrace(); // 是否ajax請求 if (isAjax(reqest)) { return JSONResult.errorException(e.getMessage()); } else { ModelAndView mav = new ModelAndView(); mav.addObject("exception", e); mav.addObject("url", reqest.getRequestURL()); mav.setViewName(ERROR_VIEW); return mav; } } public static boolean isAjax(HttpServletRequest httpRequest){ return (httpRequest.getHeader("X-Requested-With") != null && "XMLHttpRequest" .equals( httpRequest.getHeader("X-Requested-With")) ); } }
說明:
1、注解@ControllerAdvice表示這是一個控制器增強類,當控制器發生異常就會被此攔截器被攔截。
2、注解@ExceptionHandler 定義攔截的異常類,可以獲取拋出的異常信息。這里可以定義多個攔截方法,攔截不同的異常類,並且可以獲取拋出的異常信息,自由度更大。
2. 錯誤頁面
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8" /> <title>捕獲全局異常</title> </head> <body> <h1 style="color: red">發生錯誤:</h1> <div th:text="${url}"></div> <div th:text="${exception.message}"></div> </body> </html>
說明:這里用的是thymeleaf 模板,這個之前介紹過:《SpringBoot入門系列(四)整合模板引擎Thymeleaf》
3. 測試類
創建一個測試異常的controller
package com.weiz.controller; import com.weiz.utils.JSONResult; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller @RequestMapping("err") public class ErrorController { @RequestMapping("/error") public String error() { int a = 1 / 0; return "thymeleaf/error"; } @RequestMapping("/ajaxerror") public String ajaxerror() { return "thymeleaf/ajaxerror"; } @RequestMapping("/getAjaxerror") @ResponseBody public JSONResult getAjaxerror() { int a = 1 / 0; return JSONResult.ok(); } }
測試
在瀏覽器中輸入:http://localhost:8088/err/error
最后
以上,就把Spring Boot統一異常處理講完了。這里只介紹了使用@ControllerAdvice注解實現異常處理的方法,還有ErrorController的實現方式,大家可以去了解。
注解@ControllerAdvice方式只能處理控制器拋出的異常,而類ErrorController方式可以處理所有的異常,包括未進入控制器的錯誤,比如404,401等錯誤。