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ì)有什么問題。但是在測試過程中,我發(fā)現(xiàn)統(tǒng)一處理異常的方法一直沒有被調(diào)用,即使我嘗試了很多方法也沒有解決。
直到我看到一個(gè)帖子提到,被 @RestControllerAdvice 標(biāo)注的類必須單獨(dú)放到一個(gè)文件夾中,我半信半疑地創(chuàng)建了一個(gè)名為 "a" 的文件夾,并將 GlobalExceptionHandler 類放進(jìn)去后重新測試。
令我沒想到的是,異常發(fā)生時(shí)確實(shí)跳轉(zhuǎn)到了統(tǒng)一處理的方法中。
然后,我又將文件夾的名字改為 "exceptionHandler" 后重新測試,結(jié)果又無法跳轉(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)行測試,問題就得到了解決。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- SpringBoot中@RestControllerAdvice注解實(shí)現(xiàn)全局異常處理類
- springboot的統(tǒng)一異常處理,使用@RestControllerAdvice詳解
- SpringBoot項(xiàng)目中@RestControllerAdvice全局異常失效問題的解決
- SpringBoot中@RestControllerAdvice注解的使用
- SpringBoot的@RestControllerAdvice作用詳解
- SpringBoot常用注解@RestControllerAdvice詳解
- SpringBoot中的@RestControllerAdvice注解詳解
- SpringBoot?@RestControllerAdvice注解對(duì)返回值統(tǒng)一封裝的處理方法
- SpringBoot中@RestControllerAdvice 全局異常處理的實(shí)現(xiàn)
相關(guān)文章
使用Java代碼將IP地址轉(zhuǎn)換為int類型的方法
這篇文章主要介紹了使用Java代碼將IP地址轉(zhuǎn)換為int類型的方法,這也是各大計(jì)算機(jī)考試和ACM以及面試的常見基礎(chǔ)問題,需要的朋友可以參考下2015-08-08Java設(shè)計(jì)模式之策略模式詳細(xì)解析
這篇文章主要介紹了Java設(shè)計(jì)模式之策略模式詳細(xì)解析,策略模式中,定義算法族,分別封裝起來,讓他們之間可以相互轉(zhuǎn)化,此模式讓算法的變化獨(dú)立于使用算法的客戶,需要的朋友可以參考下2023-11-11Java利用httpclient通過get、post方式調(diào)用https接口的方法
這篇文章主要介紹了Java利用httpclient通過get、post方式調(diào)用https接口的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02Java實(shí)現(xiàn)的對(duì)稱加密算法AES定義與用法詳解
這篇文章主要介紹了Java實(shí)現(xiàn)的對(duì)稱加密算法AES,結(jié)合實(shí)例形式分析了對(duì)稱加密算法AES的定義、特點(diǎn)、用法及使用場景,需要的朋友可以參考下2018-04-04SpringBoot中定時(shí)任務(wù)@Scheduled的多線程使用詳解
這篇文章主要為大家詳細(xì)介紹了pring Boot定時(shí)任務(wù)@Scheduled的多線程原理以及如何加入線程池來處理定時(shí)任務(wù),感興趣的可以了解一下2023-04-04應(yīng)用Java泛型和反射導(dǎo)出CSV文件的方法
這篇文章主要介紹了應(yīng)用Java泛型和反射導(dǎo)出CSV文件的方法,通過一個(gè)自定義函數(shù)結(jié)合泛型與反射的應(yīng)用實(shí)現(xiàn)導(dǎo)出CSV文件的功能,具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2014-12-12SpringBoot Event 事件如何實(shí)現(xiàn)異步延遲執(zhí)行
這篇文章主要介紹了Spring Boot Event 事件如何實(shí)現(xiàn)異步延遲執(zhí)行問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02