SpringBoot中異常處理實戰(zhàn)記錄
一、背景
在我們編寫程序的過程中,程序中可能隨時發(fā)生各種異常,那么我們如何優(yōu)雅的處理各種異常呢?
二、需求
1、攔截系統(tǒng)中部分異常,返回自定義的響應。
比如:
系統(tǒng)發(fā)生HttpRequestMethodNotSupportedException異常,我們需要返回如下信息。
http的狀態(tài)碼:返回 405
{
code: 自定義異常碼,
message: 錯誤消息
}
2、實現(xiàn)自定義異常的攔截
攔截我們自己寫的 BizException
三、編寫一些異常基礎代碼
1、引入jar包
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies>
注意:
引入spring-boot-starter-validation是為了驗證請求的中的參數(shù),然后當參數(shù)不滿足時拋出異常。
2、定義一個自定義異常
public class BizException extends RuntimeException {
public BizException() {
}
public BizException(String message) {
super(message);
}
public BizException(String message, Throwable cause) {
super(message, cause);
}
public BizException(Throwable cause) {
super(cause);
}
public BizException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
解釋
提供一個 /exception/password api,需要傳遞一個password參數(shù)
1、當不傳遞 password 參數(shù)時將拋出MethodArgumentNotValidException異常。
2、當password傳遞exception參數(shù)時,則拋出BizException異常。
4、測試
1、不傳遞password參數(shù)響應是什么
1、使用默認的DefaultHandlerExceptionResolver處理
這個類DefaultHandlerExceptionResolver是默認自動配置的。

從上圖中可以看出有一個默認字段的返回值

2、使用ResponseEntityExceptionHandler處理
1、編寫異常處理代碼-使用默認的邏輯
@RestControllerAdvice
public class RestExceptionHandler extends ResponseEntityExceptionHandler {
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
// 此處自定義返回值
return super.handleMethodArgumentNotValid(ex, headers, status, request);
}
}
可以看到handleMethodArgumentNotValid方法直接調用父類的方法,即使用默認的處理方式。

從上圖中可以看出返回值是空
2、編寫異常處理代碼-返回值返回自定義內容
@Component
@RestControllerAdvice
public class RestExceptionHandler extends ResponseEntityExceptionHandler {
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
// 此處自定義返回值
return super.handleMethodArgumentNotValid(ex, headers, status, request);
}
@Override
protected ResponseEntity<Object> handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
Set<HttpMethod> supportedMethods = ex.getSupportedHttpMethods();
// 自定義請求返回值
Map<String, Object> body = new HashMap<>(4);
body.put("code", "錯誤碼");
body.put("message", "當前請求的方法不支持,支持的請求方法為:" + supportedMethods);
return new ResponseEntity<>(body, headers, status);
}
}
由上面的代碼可知handleHttpRequestMethodNotSupported方法返回了自定義的body。

從上圖中可以看出,返回了我們自己定義的返回值。
2、password參數(shù)傳遞exception1、使用ResponseEntityExceptionHandler或DefaultHandlerExceptionResolver處理

由上圖可知返回結果不對,我們需要自定義返回結果。
2、返回自定義異常
1、編寫B(tài)izException處理代碼
@RestControllerAdvice
public class BizExceptionHandler {
@ExceptionHandler(BizException.class)
public ResponseEntity<Object> handleBizException(BizException exception) {
// 自定義請求返回值
Map<String, Object> body = new HashMap<>(4);
body.put("code", "錯誤碼");
body.put("message", "異常信息為:" + exception.getMessage());
return new ResponseEntity<>(body, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
2、測試返回結果

從上圖可知返回了自定義信息
四、注意事項
1、如果實現(xiàn)自定義異常處理類上使用@RestControllerAdvice注解方法上使用@ExceptionHandler來處理特定的異常
2、ResponseEntityExceptionHandler默認處理那些異常

3、使用了ResponseEntityExceptionHandler后,為什么發(fā)生了異常后返回體為空

默認情況下,實現(xiàn)了 ResponseEntityExceptionHandler這個類后,這個類處理的所有異常的響應結果都是 null,如果想返回別的值需要我們自己去處理。
五、總結
1、如果我們想處理自定義異常,則可以使用 @RestControllerAdvice || @ControllerAdvice 配置@ExceptionHandler來使用。
2、如果我們實現(xiàn)了ResponseEntityExceptionHandler來處理異常,那么默認的異常的響應結果為空,如果想不為空,則需要我們自己處理。
3、默認情況下,標準的Spring MVC異常會通過DefaultHandlerExceptionResolver來處理。
六、代碼實現(xiàn)
https://gitee.com/huan1993/spring-cloud-parent/tree/master/springboot/springboot-exception-handler
七、參考文檔

到此這篇關于SpringBoot中異常處理的文章就介紹到這了,更多相關SpringBoot異常處理內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Spring Boot Admin 動態(tài)修改日志級別的方法步驟
這篇文章主要介紹了Spring Boot Admin 動態(tài)修改日志級別的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-08-08
多線程-lock與lockInterruptibly的區(qū)別及說明
文章主要討論了Java中ReentrantLock的lock和lockInterruptibly方法的區(qū)別,以及AQS中的雙向鏈表設計,lock方法不響應中斷,而lockInterruptibly方法會響應中斷,AQS的雙向鏈表設計使得線程管理更加高效和靈活,適用于高并發(fā)場景2025-02-02
在IntelliJ IDEA中多線程并發(fā)代碼的調試方法詳解
這篇文章主要介紹了在IntelliJ IDEA中多線程并發(fā)代碼的調試方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-08-08
Spring boot2基于Mybatis實現(xiàn)多表關聯(lián)查詢
這篇文章主要介紹了Spring boot2基于Mybatis實現(xiàn)多表關聯(lián)查詢,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-04-04
Intellij IDEA 如何通過數(shù)據(jù)庫表生成帶注解的實體類(圖文詳細教程)
這篇文章主要介紹了Intellij IDEA 如何通過數(shù)據(jù)庫表生成帶注解的實體類(圖文詳細教程),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-11-11
Java concurrency集合之LinkedBlockingDeque_動力節(jié)點Java學院整理
LinkedBlockingDeque是雙向鏈表實現(xiàn)的雙向并發(fā)阻塞隊列。該阻塞隊列同時支持FIFO和FILO兩種操作方式,即可以從隊列的頭和尾同時操作(插入/刪除);并且,該阻塞隊列是支持線程安全。2017-06-06
關于SpringBoot2.7.6連接nacos遇到的一些問題
這篇文章主要介紹了關于SpringBoot2.7.6連接nacos遇到的一些問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-06-06

