SpringBoot中@RestControllerAdvice @ExceptionHandler異常統(tǒng)一處理類失效原因分析
項(xiàng)目原來的處理方式
在我的項(xiàng)目中,我原本只使用了 @ExceptionHandler 注解,并通過繼承的方式實(shí)現(xiàn)了統(tǒng)一異常處理。
我創(chuàng)建了一個(gè)名為 BaseController 的父類,其中包含了以下代碼:
public class BaseController { @ExceptionHandler(Exception.class) public RestResult handleException(Throwable e) { //定義異常處理的響應(yīng)數(shù)據(jù)模型 RestResult result = new RestResult(); result.setSuccess(false); result.setData(e.getMessage()); result.setErrorCode(500); e.printStackTrace(); return result; } }
然后,我讓項(xiàng)目中需要統(tǒng)一異常管理的 @Controller 類都繼承了 BaseController。
例如,我有一個(gè)名為 UserController 的控制器:
@RequestMapping("/user") public class UserController extends BaseController { ··· }
通過這種方式,我成功實(shí)現(xiàn)了統(tǒng)一異常處理,但是這種方法需要讓所有的 @Controller 類都繼承BaseController,有些繁瑣。
使用@RestControllerAdvice和@ExceptionHandler組合
后來,我在網(wǎng)上找到了使用 @RestControllerAdvice 和 @ExceptionHandler 組合的方法。
我創(chuàng)建了一個(gè)名為 GlobalExceptionHandler 的類,其中包含了以下代碼:
@RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) public RestResult handleException(Throwable e) { //定義異常處理的響應(yīng)數(shù)據(jù)模型 RestResult result = new RestResult(); result.setSuccess(false); result.setData(e.getMessage()); result.setErrorCode(500); e.printStackTrace(); return result; } }
遇到的問題描述
起初,我以為這種方法不會(huì)有什么問題。但是在測(cè)試過程中,我發(fā)現(xiàn)統(tǒng)一處理異常的方法一直沒有被調(diào)用,即使我嘗試了很多方法也沒有解決。
直到我看到一個(gè)帖子提到,被 @RestControllerAdvice 標(biāo)注的類必須單獨(dú)放到一個(gè)文件夾中,我半信半疑地創(chuàng)建了一個(gè)名為 "a" 的文件夾,并將 GlobalExceptionHandler 類放進(jìn)去后重新測(cè)試。
令我沒想到的是,異常發(fā)生時(shí)確實(shí)跳轉(zhuǎn)到了統(tǒng)一處理的方法中。
然后,我又將文件夾的名字改為 "exceptionHandler" 后重新測(cè)試,結(jié)果又無(wú)法跳轉(zhuǎn)到統(tǒng)一處理的方法中。
此時(shí)我已經(jīng)發(fā)現(xiàn)了問題所在。由于我將控制器代碼放在了名為 "controller" 的文件夾中,一開始我將 "GlobalExceptionHandler" 類放到名為 "a"的文件夾,它在 "controller" 的首字母 "c" 上面;后來我我將 "GlobalExceptionHandler" 類放到以 "e" 開頭的文件夾,它在 "controller" 的首字母 "c" 下面。
因此,這可能是由于 Spring Bean 加載順序的問題。
解決
只需要在GlobalExceptionHandler類中添加@Order注解,以確保它優(yōu)先加載就沒問題了。
@Order(9999) @RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) public RestResult handleException(Throwable e) { //定義異常處理的響應(yīng)數(shù)據(jù)模型 RestResult result = new RestResult(); result.setSuccess(false); result.setData(e.getMessage()); result.setErrorCode(500); e.printStackTrace(); return result; } }
添加了 @Order 注解后,重新進(jìn)行測(cè)試,問題就得到了解決。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- SpringBoot如何實(shí)現(xiàn)調(diào)用controller和Service層方法
- springboot中的controller參數(shù)映射問題小結(jié)
- springboot中Controller內(nèi)文件上傳到本地及阿里云操作方法
- springboot如何通過controller層實(shí)現(xiàn)頁(yè)面切換
- springboot Controller直接返回String類型帶來的亂碼問題及解決
- SpringBoot之controller參數(shù)校驗(yàn)詳解
- springboot中@RestController注解實(shí)現(xiàn)
- SpringBoot通過注解監(jiān)測(cè)Controller接口的代碼示例
- springboot controller參數(shù)注入方式
- SpringBoot和MybatisPlus實(shí)現(xiàn)通用Controller示例
相關(guān)文章
java調(diào)用FFmpeg實(shí)現(xiàn)視屏壓縮功能的詳細(xì)步驟
這篇文章主要介紹了java調(diào)用FFmpeg實(shí)現(xiàn)視屏壓縮功能,本文簡(jiǎn)單的展示了java調(diào)用FFmpeg命令實(shí)現(xiàn)視屏的壓縮的詳細(xì)步驟,需要的朋友可以參考下2021-09-09深入理解SpringMVC的參數(shù)綁定與數(shù)據(jù)響應(yīng)機(jī)制
本文將深入探討SpringMVC的參數(shù)綁定方式,包括基本類型、對(duì)象、集合等類型的綁定方式,以及如何處理參數(shù)校驗(yàn)和異常。同時(shí),本文還將介紹SpringMVC的數(shù)據(jù)響應(yīng)機(jī)制,包括如何返回JSON、XML等格式的數(shù)據(jù),以及如何處理文件上傳和下載。2023-06-06一文帶你搞懂Java中Synchronized和Lock的原理與使用
這篇文章主要為大家詳細(xì)介紹了Java中Synchronized和Lock的原理與使用,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Java有一定的幫助,需要的可以參考一下2023-04-04JAVA如何把數(shù)據(jù)庫(kù)的數(shù)據(jù)處理成樹形結(jié)構(gòu)
本文介紹了JAVA如何把數(shù)據(jù)庫(kù)的數(shù)據(jù)處理成樹形結(jié)構(gòu),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09Java中的字節(jié)流InputStream和OutputStream詳解
這篇文章主要介紹了Java中的字節(jié)流InputStream和OutputStream詳解,繼承自InputStream的流都是用于向程序中輸入數(shù)據(jù),且數(shù)據(jù)的單位為字節(jié)8bit,我們看到的具體的某一些管道,凡是以InputStream結(jié)尾的管道,都是以字節(jié)的形式向我們的程序輸入數(shù)據(jù),需要的朋友可以參考下2023-10-10Java中連接數(shù)據(jù)庫(kù)方式詳細(xì)步驟記錄
這篇文章主要介紹了Java中連接數(shù)據(jù)庫(kù)方式的詳細(xì)步驟,包括添加依賴、建立連接、執(zhí)行SQL語(yǔ)句、處理結(jié)果集和關(guān)閉連接,還討論了數(shù)據(jù)庫(kù)連接池的使用,需要的朋友可以參考下2025-01-01使用Spring AOP監(jiān)控指定方法執(zhí)行時(shí)間的代碼詳解
這篇文章主要介紹了使用Spring AOP監(jiān)控指定方法執(zhí)行時(shí)間,文中通過代碼示例給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-08-08