軟件開發(fā)過程中有一大半的時間都是在處理各種異常情況,并且各種異常還防不勝防杯道,稍有不慎就會有遺漏。導(dǎo)致代碼中出現(xiàn)大量的try {...} catch {...} finally {...}代碼塊唯灵,不僅難易維護钝鸽,并且也不優(yōu)雅,會被其他接手同學(xué)背后喊罵唾那,甚至自己都會覺得寫的太爛了访锻。這種情況SpringBoot框架當(dāng)然也有想到,因此Spring3.2增加了@ControllerAdvice結(jié)合@ExceptionHandler進行全局異常處理闹获,接下來將詳細(xì)介紹全局統(tǒng)一異常處理的方法
Spring在3.2版本增加了@ControllerAdvice期犬,可以與@ExceptionHandler、@InitBinder避诽、@ModelAttribute等注解配套使用龟虎,對于異常處理使用@ExceptionHandler即可
直觀的想法就是在每個Controller定義一套異常處理方法(由于每個Controller的異常有可能不一樣,且數(shù)量眾多)茎用,并在方法上增加@ExceptionHandler注解遣总,當(dāng)出現(xiàn)各種異常是,就可以使用該方法進行處理轨功,這種方案想想都不優(yōu)雅旭斥,需要每個Controller都處理,升級方法就是繼承BaseController之類的古涧,但是也不優(yōu)雅垂券,一個簡單的Controller竟然需要繼承,如果還有其他基類需要繼承則該方案就行不通了羡滑。針對這種困惑菇爪,SpringBoot也想到了即是用@ControllerAdvice,該注解可以把異常處理器應(yīng)用到所有的Controller而不是單個的柒昏,基于該注解(只需要在類簽名增加該注解)凳宙,可以單獨定義一個異常處理類,在類中定義一套各種的異常處理機制职祷,就可以統(tǒng)一對不同階段氏涩、不同異常進行處理,避免重復(fù)的冗余代碼有梆,也避免遺漏一些異常是尖,更避免了頻繁修改代碼。
@RestControllerAdvice + @ExceptionHandler 統(tǒng)一全局異常處理
本文介紹@RestControllerAdvice(=@ControllerAdvice + @ResponseBody) + @ExceptionHandler進行全局的Controller層異常處理泥耀,避免在Controller層進行大量的try-catch饺汹,而且可以結(jié)合@Validation注解校驗器一起處理,無需手動判斷綁定校驗結(jié)果BindingResult/Errors
優(yōu)缺點
優(yōu)點:將Controller層的異常和數(shù)據(jù)校驗的異常進行統(tǒng)一處理痰催,減少模板代碼兜辞,減少編碼量迎瞧,提升擴展性和可維護性
缺點:只能處理Controller層未捕獲(往外拋)的異常,對于Interceptor(攔截器)層的異常弦疮,Spring框架層的異常夹攒,就無能為力了
使用實例
@RestControllerAdvice定義全局異常處理類
@RestControllerAdvice
public class GlobalExceptionHandler {
}
請確保GlobalExceptionHandler類能被掃描到并裝載進Spring容器中
@ExceptionHandler注解聲明異常處理方法
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public Object exceptionHandler(Exception e) {
log.error(e.getMessage, e);
return "Exception ..."; // 可以根據(jù)具體場景調(diào)整返回數(shù)據(jù)結(jié)構(gòu)體
}
}
該exceptionHandler會自動處理Controller層拋出的Exception及其子類的異常,參數(shù)Exception就是Controller拋出的異常
處理自定義異常
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(BusinessException.class)
public Object exceptionHandler(BusinessException e) {
log.error(e.getMessage, e);
return "BusinessException ..."; // 可以根據(jù)具體場景調(diào)整返回數(shù)據(jù)結(jié)構(gòu)體
}
}
public class BusinessException extends RuntimeException {
public BusinessException(String message) {
super(message);
}
public BusinessException(String message, Throwable th) {
super(message, th);
}
}
參考
統(tǒng)一異常處理介紹及實戰(zhàn)
使用@ControllerAdvice + @ExceptionHandler 全局處理Controller 層異常
Spring進階之@ControllerAdvice與統(tǒng)一異常處理
優(yōu)雅的處理你的Java異常