javascript
Springboot对web应用的统一异常处理
我們在做Web應用的時候,請求處理過程中發生錯誤是非常常見的情況。Spring Boot提供了一個默認的映射:/error,當處理中拋出異常之后,會轉到該請求中處理,并且該請求有一個全局的錯誤頁面用來展示異常內容。
默認情況下,Spring Boot為兩種情況提供了不同的響應方式
1、當瀏覽器發送請求頭是Accept: text/html;Spring Boot默認會響應一個html文檔內容,稱作“Whitelabel Error Page”。
2、當使用postman等調試工具發送請求一個不存在的url或服務端處理發生異常時,Spring Boot會返回類似如下的Json格式字符串信息。
Spring Boot 默認提供了程序出錯的結果映射路徑/error。這個/error請求會在BasicErrorController中處理,其內部是通過判斷請求頭中的Accept的內容是否為text/html來區分請求是來自客戶端瀏覽器(瀏覽器通常默認自動發送請求頭內容Accept:text/html)還是客戶端接口的調用,以此來決定返回頁面視圖還是 JSON 消息內容。處理源碼如下:
全局統一異常處理
Springboot中定義了默認的error錯誤映射,但是在實際項目使用中,這些默認的錯誤映射對我們來說并不實用,所以我們需要實現符合實際業務場景的異常提示。本文我們來學習springboot針對web應用的統一異常處理。
- 局部異常處理 @Controller + @ExceptionHandler
- 全局異常處理 @ControllerAdvice + @ExceptionHandler
1、局部異常處理 @Controller + @ExceptionHandler
局部異常主要用到的是@ExceptionHandler注解,此注解注解到類的方法上,當此注解里定義的異常拋出時,此方法會被執行。如果@ExceptionHandler所在的類是@Controller,則此方法只作用在此類。如果@ExceptionHandler所在的類帶有@ControllerAdvice注解,則此方法會作用在全局。
2、全局異常處理 @ControllerAdvice + @ExceptionHandler
SpringBoot全局異常處理
SpringBoot中有一個ControllerAdvice的注解,使用該注解表示開啟了全局異常的捕獲,我們只需在自定義一個方法使用ExceptionHandler注解然后定義捕獲異常的類型即可對這些捕獲的異常進行統一的處理。
注意:基于@ControllerAdvice注解的全局異常統一處理只能針對于Controller層的異常,簡單的說,進入Controller層的錯誤才會由@ControllerAdvice處理,攔截器拋出的錯誤以及訪問錯誤地址的情況@ControllerAdvice處理不了,由SpringBoot默認的異常處理機制處理。
使用@ControllerAdvice或者@RestControllerAdvice定義統一的全局異常處理類,而不是在controller中逐個定義。使用@ExceptionHandler來定義函數針對的異常類型。
@RestControllerAdvice 類似于 @RestController 與 @Controller的區別
全局統一異常示例
上面說了springboot異常原理,在實際開發中,如果是要實現RESTful API,那么默認的JSON錯誤信息就不是我們想要的(本質上,只需在@ExceptionHandler之后加入@ResponseBody,就能讓處理函數return的內容轉換為JSON格式。),這時候就需要統一一下JSON格式,所以常常自己要封裝一下。封裝后的數據返回如下:
正確的時候
{code:200,msg:“獲取列表成功”,data:{ queryList :[]} }錯誤的時候
{code:500,msg:“未知異常,請聯系管理員” } import java.io.Serializable;/*** 自定義標準響應格式* @author: liumengbing* @date: 2019/05/31 16:35**/ public class ResponseModel implements Serializable {private Integer status;//響應狀態碼private String message;//響應信息private Object data;//響應內容public ResponseModel() {}public ResponseModel(Integer status, String message) {this.status = status;this.message = message;}public ResponseModel(Integer status, String message, Object data) {this.status = status;this.message = message;this.data = data;}//getter and setter …} /*** 自定義異常,這里要繼承runtimeException是因為spring框架對運行時異常會進行回滾,如果是exception就不會了* @author: liumengbing* @date: 2019/05/31 17:03**/ public class MyException extends RuntimeException {private int code;private Object data;public MyException() {}public MyException(int code, String message) {super(message);this.code = code;}public MyException(int code, String message, Object data) {super(message);this.code = code;this.data = data;}public int getCode() {return code;}public Object getData() {return data;}@Overridepublic String toString() {return "MyException{" +"code=" + code +", data=" + data +", message=" + getMessage() +'}';} } /*** 全局異常處理類* @author: liumengbing* @date: 2019/05/31 16:36**/ @ControllerAdvice public class GlobalExceptionHandler {/*** 當發生Exception異常時,執行此方法* @param e* @return*/@ExceptionHandler(Exception.class)@ResponseBodypublic ResponseModel exHandler(Exception e) {// 判斷發生異常的類型是除0異常則做出響應if (e instanceof ArithmeticException) {return new ResponseModel(500,"發生了除0異常");}// 未知的異常做出響應return new ResponseModel(500,"發生了未知異常");}/*** 當發生MyException異常時,執行此方法* @param myException* @return*/@ExceptionHandler(MyException.class)@ResponseBodypublic ResponseModel exHandler(MyException myException) {return new ResponseModel(500,"發生了MyException");}}測試接口
/*** @author: liumengbing* @date: 2019/05/31 16:35**/ @Controller public class TestController {@RequestMapping("/test")@ResponseBodypublic String test() {throw new MyException();} }總結
以上是生活随笔為你收集整理的Springboot对web应用的统一异常处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用fastjson提供的接口实现自定义
- 下一篇: SpringMVC配置类WebMvcCo