SpringBoot中異常處理實(shí)戰(zhàn)記錄
一、背景
在我們編寫程序的過程中,程序中可能隨時(shí)發(fā)生各種異常,那么我們?nèi)绾蝺?yōu)雅的處理各種異常呢?
二、需求
1、攔截系統(tǒng)中部分異常,返回自定義的響應(yīng)。
比如:
系統(tǒng)發(fā)生HttpRequestMethodNotSupportedException異常,我們需要返回如下信息。
http的狀態(tài)碼:返回 405
{ code: 自定義異常碼, message: 錯(cuò)誤消息 }
2、實(shí)現(xiàn)自定義異常的攔截
攔截我們自己寫的 BizException
三、編寫一些異常基礎(chǔ)代碼
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是為了驗(yàn)證請(qǐng)求的中的參數(shù),然后當(dāng)參數(shù)不滿足時(shí)拋出異常。
2、定義一個(gè)自定義異常
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); } }
解釋
提供一個(gè) /exception/password api,需要傳遞一個(gè)password參數(shù)
1、當(dāng)不傳遞 password 參數(shù)時(shí)將拋出MethodArgumentNotValidException異常。
2、當(dāng)password傳遞exception參數(shù)時(shí),則拋出BizException異常。
4、測(cè)試
1、不傳遞password參數(shù)響應(yīng)是什么
1、使用默認(rèn)的DefaultHandlerExceptionResolver處理
這個(gè)類DefaultHandlerExceptionResolver是默認(rèn)自動(dòng)配置的。
從上圖中可以看出有一個(gè)默認(rèn)字段的返回值
2、使用ResponseEntityExceptionHandler處理
1、編寫異常處理代碼-使用默認(rèn)的邏輯
@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
方法直接調(diào)用父類的方法,即使用默認(rèn)的處理方式。
從上圖中可以看出返回值是空
2、編寫異常處理代碼-返回值返回自定義內(nèi)容
@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(); // 自定義請(qǐng)求返回值 Map<String, Object> body = new HashMap<>(4); body.put("code", "錯(cuò)誤碼"); body.put("message", "當(dāng)前請(qǐng)求的方法不支持,支持的請(qǐng)求方法為:" + supportedMethods); return new ResponseEntity<>(body, headers, status); } }
由上面的代碼可知handleHttpRequestMethodNotSupported方法返回了自定義的body。
從上圖中可以看出,返回了我們自己定義的返回值。
2、password參數(shù)傳遞exception1、使用ResponseEntityExceptionHandler或DefaultHandlerExceptionResolver處理
由上圖可知返回結(jié)果不對(duì),我們需要自定義返回結(jié)果。
2、返回自定義異常
1、編寫B(tài)izException處理代碼
@RestControllerAdvice public class BizExceptionHandler { @ExceptionHandler(BizException.class) public ResponseEntity<Object> handleBizException(BizException exception) { // 自定義請(qǐng)求返回值 Map<String, Object> body = new HashMap<>(4); body.put("code", "錯(cuò)誤碼"); body.put("message", "異常信息為:" + exception.getMessage()); return new ResponseEntity<>(body, HttpStatus.INTERNAL_SERVER_ERROR); } }
2、測(cè)試返回結(jié)果
從上圖可知返回了自定義信息
四、注意事項(xiàng)
1、如果實(shí)現(xiàn)自定義異常處理類上使用@RestControllerAdvice
注解方法上使用@ExceptionHandler
來處理特定的異常
2、ResponseEntityExceptionHandler默認(rèn)處理那些異常
3、使用了ResponseEntityExceptionHandler后,為什么發(fā)生了異常后返回體為空
默認(rèn)情況下,實(shí)現(xiàn)了 ResponseEntityExceptionHandler
這個(gè)類后,這個(gè)類處理的所有異常的響應(yīng)結(jié)果都是 null
,如果想返回別的值需要我們自己去處理。
五、總結(jié)
1、如果我們想處理自定義異常,則可以使用 @RestControllerAdvice
|| @ControllerAdvice
配置@ExceptionHandler
來使用。
2、如果我們實(shí)現(xiàn)了ResponseEntityExceptionHandler
來處理異常,那么默認(rèn)的異常的響應(yīng)結(jié)果為空,如果想不為空,則需要我們自己處理。
3、默認(rèn)情況下,標(biāo)準(zhǔn)的Spring MVC異常會(huì)通過DefaultHandlerExceptionResolver
來處理。
六、代碼實(shí)現(xiàn)
https://gitee.com/huan1993/spring-cloud-parent/tree/master/springboot/springboot-exception-handler
七、參考文檔
到此這篇關(guān)于SpringBoot中異常處理的文章就介紹到這了,更多相關(guān)SpringBoot異常處理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot異常處理之異常顯示的頁面問題
- SpringBoot優(yōu)雅地實(shí)現(xiàn)全局異常處理的方法詳解
- Springboot項(xiàng)目異常處理及返回結(jié)果統(tǒng)一
- springboot處理異常的5種方式
- 如何在SpringBoot項(xiàng)目里進(jìn)行統(tǒng)一異常處理
- SpringBoot接口如何統(tǒng)一異常處理
- springboot?全局異常處理和統(tǒng)一響應(yīng)對(duì)象的處理方式
- SpringBoot詳解實(shí)現(xiàn)自定義異常處理頁面方法
- SpringBoot錯(cuò)誤處理流程深入詳解
相關(guān)文章
Spring + mybatis + mysql使用事物的幾種方法總結(jié)
這篇文章主要給大家總結(jié)介紹了關(guān)于Spring + mybatis + mysql使用事物的幾種方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-05-05spring boot啟動(dòng)時(shí)加載外部配置文件的方法
這篇文章主要給大家介紹了關(guān)于spring boot啟動(dòng)時(shí)加載外部配置文件的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2018-02-02Spring Boot詳解各類請(qǐng)求和響應(yīng)的處理方法
平時(shí)只是在用SpringBoot框架,但并沒有詳細(xì)研究過請(qǐng)求和響應(yīng)執(zhí)行的一個(gè)具體過程,所以本文主要來梳理一下SpringBoot請(qǐng)求和響應(yīng)的處理過程2022-07-07解決Mybatis?plus實(shí)體類屬性與表字段不一致的問題
這篇文章主要介紹了Mybatis?plus實(shí)體類屬性與表字段不一致解決方法,文末給大家提到了Mybatis-plus中數(shù)據(jù)庫表名和表字段名的相關(guān)知識(shí),需要的朋友可以參考下2022-07-07java Callable與Future的詳解及實(shí)例
這篇文章主要介紹了java Callable與Future的詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-01-01spring boot使用@Async異步注解的實(shí)現(xiàn)原理+源碼
通常我們都是采用多線程的方式來實(shí)現(xiàn)上述業(yè)務(wù)功能,但spring 提供更優(yōu)雅的方式來實(shí)現(xiàn)上述功能,就是@Async 異步注解,在方法上添加@Async,spring就會(huì)借助AOP,異步執(zhí)行方法,接下來通過本文給大家介紹spring boot異步注解的相關(guān)知識(shí),一起看看吧2021-06-06詳解Java?ReentrantLock可重入,可打斷,鎖超時(shí)的實(shí)現(xiàn)原理
前面講解了ReentrantLock加鎖和解鎖的原理實(shí)現(xiàn),但是沒有闡述它的可重入、可打斷以及超時(shí)獲取鎖失敗的原理,本文就重點(diǎn)講解這三種情況,需要的可以了解一下2022-10-10