Spring Boot @RestControllerAdvice全局異常處理最佳實踐
前言
在開發(fā)Spring Boot應(yīng)用時,優(yōu)雅地處理異常是保證系統(tǒng)健壯性和用戶體驗的關(guān)鍵。本文將詳細(xì)介紹如何使用@RestControllerAdvice實現(xiàn)全局異常處理,并分享實際開發(fā)中的最佳實踐。
一、為什么要使用全局異常處理?
代碼復(fù)用:避免在每個Controller中重復(fù)編寫try-catch
統(tǒng)一響應(yīng)格式:標(biāo)準(zhǔn)化錯誤返回結(jié)構(gòu)
異常分類處理:針對不同類型異常定制處理邏輯
減少樣板代碼:讓業(yè)務(wù)邏輯更專注于核心流程
二、核心注解解析
1. @RestControllerAdvice
@RestControllerAdvice是@ControllerAdvice和@ResponseBody的組合注解,主要功能:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ControllerAdvice
@ResponseBody
public @interface RestControllerAdvice {
// 可指定包路徑或控制器類
@AliasFor(annotation = ControllerAdvice.class)
String[] value() default {};
}2. @ExceptionHandler
用于標(biāo)注處理特定異常的方法:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExceptionHandler {
// 指定要處理的異常類數(shù)組
Class<? extends Throwable>[] value() default {};
}三、實戰(zhàn)代碼實現(xiàn)
以下是完整全局異常處理器實現(xiàn):
他會對于ExceptionHandler指定的異常進(jìn)行處理,底層是通過AOP的技術(shù)實現(xiàn)的。
import com.sheep.shrine.result.JSONResult;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* 全局異常處理器
* @RestControllerAdvice = @ControllerAdvice + @ResponseBody
*/
@RestControllerAdvice
public class GlobalExceptionHandler {
/**
* 處理自定義業(yè)務(wù)異常
*/
@ExceptionHandler(GlobleException.class)
public JSONResult handleBusinessException(GlobleException e) {
e.printStackTrace();
return JSONResult.error(e.getMessage());
}
/**
* 處理所有未捕獲異常
*/
@ExceptionHandler(Exception.class)
public JSONResult handleSystemException(Exception e) {
e.printStackTrace();
return JSONResult.error("系統(tǒng)異常,正在毆打程序員...", "50000");
}
}四、進(jìn)階使用技巧
1. 異常分類處理
// 處理數(shù)據(jù)校驗異常
@ExceptionHandler(MethodArgumentNotValidException.class)
public JSONResult handleValidException(MethodArgumentNotValidException e) {
String message = e.getBindingResult().getAllErrors()
.stream()
.map(DefaultMessageSourceResolvable::getDefaultMessage)
.collect(Collectors.joining("; "));
return JSONResult.error(message);
}
// 處理數(shù)據(jù)庫異常
@ExceptionHandler(DataAccessException.class)
public JSONResult handleDataAccessException(DataAccessException e) {
log.error("數(shù)據(jù)庫操作異常", e);
return JSONResult.error("數(shù)據(jù)庫服務(wù)異常");
}2. 響應(yīng)狀態(tài)碼控制
@ExceptionHandler(UnauthorizedException.class)
@ResponseStatus(HttpStatus.FORBIDDEN)
public JSONResult handleUnauthorizedException(UnauthorizedException e) {
return JSONResult.error("無權(quán)限訪問", "403");
}3. 日志記錄優(yōu)化
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public JSONResult handleException(Exception e) {
log.error("系統(tǒng)異常: {}", e.getMessage(), e);
return JSONResult.error("系統(tǒng)繁忙");
}
}五、最佳實踐建議
異常分類細(xì)化:不要只用一個Exception.class處理所有異常
敏感信息過濾:生產(chǎn)環(huán)境不要返回堆棧信息
錯誤碼規(guī)范:制定統(tǒng)一的錯誤碼體系
日志完善:關(guān)鍵異常必須記錄完整上下文
性能考慮:異常處理邏輯應(yīng)盡量輕量
六、常見問題解答
Q1:全局異常處理器不生效怎么辦?
檢查是否在Spring掃描路徑下
確認(rèn)沒有其他異常處理器覆蓋
檢查是否有Filter提前處理了異常
Q2:如何測試全局異常處理器?
@SpringBootTest
class GlobalExceptionHandlerTest {
@Autowired
private WebApplicationContext context;
private MockMvc mockMvc;
@BeforeEach
void setup() {
mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
}
@Test
void testBusinessException() throws Exception {
mockMvc.perform(get("/api/test-exception"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value("50000"));
}
}Q3:如何與FeignClient集成?
@Configuration
public class FeignConfig {
@Bean
public ErrorDecoder errorDecoder() {
return (methodKey, response) -> {
// 將Feign異常轉(zhuǎn)換為自定義異常
return new BusinessException("遠(yuǎn)程服務(wù)調(diào)用失敗");
};
}
}七、總結(jié)
通過@RestControllerAdvice實現(xiàn)全局異常處理可以:
提高代碼可維護(hù)性
增強系統(tǒng)健壯性
改善用戶體驗
便于監(jiān)控報警
到此這篇關(guān)于Spring Boot @RestControllerAdvice全局異常處理最佳實踐的文章就介紹到這了,更多相關(guān)Spring Boot @RestControllerAdvice全局異常內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java連接合并2個數(shù)組(Array)的5種方法例子
最近在寫代碼時遇到了需要合并兩個數(shù)組的需求,突然發(fā)現(xiàn)以前沒用過,于是研究了一下合并數(shù)組的方式,這篇文章主要給大家介紹了關(guān)于Java連接合并2個數(shù)組(Array)的5種方法,需要的朋友可以參考下2023-12-12
java.lang.AbstractMethodError: org.apache.xerces.dom.Documen
這篇文章主要介紹了java.lang.AbstractMethodError: org.apache.xerces.dom.DocumentImpl.setXmlVersion問題解決方法,導(dǎo)致本文問題的原因是缺少一個xerces.jar jar包,需要的朋友可以參考下2015-03-03
Spring之關(guān)于PropertyDescriptor的擴(kuò)展剖析
這篇文章主要介紹了Spring之關(guān)于PropertyDescriptor的擴(kuò)展剖析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07
快速解決springboot在yml配置了啟動端口但啟動還是8080問題
這篇文章主要介紹了快速解決springboot在yml配置了啟動端口但啟動還是8080問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-03-03

