JAVA中Spring全局異常處理@ControllerAdvice解析

一、@ControllerAdvice基礎概念

1. 什么是@ControllerAdvice?

@ControllerAdvice是Spring 3.2引入的注解,用于定義全局控制器增強組件,主要功能包括:

  • 全局異常處理(最常用)
  • 全局數據綁定
  • 全局數據預處理

2. 核心作用

  • 集中處理控制器層異常
  • 避免重復的異常處理代碼
  • 統一API錯誤響應格式
  • 減少try-catch塊污染業務代碼

二、基礎全局異常處理實現

1. 最小實現示例

@ControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(Exception.class)@ResponseBodypublic ResponseEntity<ErrorResponse> handleException(Exception ex) {ErrorResponse error = new ErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR.value(),"服務器內部錯誤",ex.getMessage());return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);}
}// 統一錯誤響應DTO
@Data
@AllArgsConstructor
class ErrorResponse {private int status;private String error;private String message;private long timestamp = System.currentTimeMillis();
}

2. 處理特定異常

@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<ErrorResponse> handleResourceNotFound(ResourceNotFoundException ex) {ErrorResponse error = new ErrorResponse(HttpStatus.NOT_FOUND.value(),"資源未找到",ex.getMessage());return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);
}

三、高級配置技巧

1. 限定控制器范圍

// 只處理指定包下的控制器
@ControllerAdvice(basePackages = "com.example.web.controllers")// 只處理帶有特定注解的控制器
@ControllerAdvice(annotations = RestController.class)// 只處理指定類
@ControllerAdvice(assignableTypes = {UserController.class, ProductController.class})

2. 異常處理優先級

Spring會按照最具體到最通用的順序匹配@ExceptionHandler

@ExceptionHandler(FileUploadException.class)  // 優先匹配
public ResponseEntity<?> handleFileUpload(FileUploadException ex) { ... }@ExceptionHandler(IOException.class)          // 次級匹配
public ResponseEntity<?> handleIO(IOException ex) { ... }@ExceptionHandler(Exception.class)            // 兜底處理
public ResponseEntity<?> handleGeneral(Exception ex) { ... }

3. 獲取請求上下文

通過注入請求對象獲取更多信息:

@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleException(Exception ex, WebRequest request) {String path = ((ServletWebRequest)request).getRequest().getRequestURI();ErrorResponse error = new ErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR.value(),"處理請求[" + path + "]時發生錯誤",ex.getMessage());return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);
}

四、常見異常處理模式

1. 業務異常處理

@ExceptionHandler(BusinessException.class)
public ResponseEntity<ErrorResponse> handleBusinessException(BusinessException ex) {ErrorResponse error = new ErrorResponse(ex.getErrorCode(),ex.getErrorType(),ex.getMessage());return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);
}

2. 數據校驗異常

@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ErrorResponse> handleValidationException(MethodArgumentNotValidException ex) {List<String> errors = ex.getBindingResult().getFieldErrors().stream().map(FieldError::getDefaultMessage).collect(Collectors.toList());ErrorResponse error = new ErrorResponse(HttpStatus.BAD_REQUEST.value(),"參數校驗失敗",errors.toString());return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);
}

3. 認證授權異常

@ExceptionHandler({AccessDeniedException.class,AuthenticationException.class
})
public ResponseEntity<ErrorResponse> handleAuthException(RuntimeException ex) {HttpStatus status = ex instanceof AccessDeniedException ? HttpStatus.FORBIDDEN : HttpStatus.UNAUTHORIZED;ErrorResponse error = new ErrorResponse(status.value(),"權限不足",ex.getMessage());return new ResponseEntity<>(error, status);
}

五、最佳實踐建議

1. 異常分類處理

建議將異常分為幾大類分別處理:

異常類型處理方式HTTP狀態碼
業務異常返回具體錯誤信息400-499
系統異常記錄日志,返回通用錯誤500
第三方服務異常記錄日志,返回服務不可用503
參數校驗異常返回詳細校驗錯誤400

2. 日志記錄策略

@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleException(Exception ex, HttpServletRequest request) {log.error("請求[{} {}]處理失敗", request.getMethod(), request.getRequestURI(), ex);// ...返回錯誤響應
}

3. 生產環境與開發環境差異

@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleException(Exception ex,Environment env) {boolean isProd = Arrays.asList(env.getActiveProfiles()).contains("prod");String message = isProd ? "服務器錯誤,請聯系管理員" : ex.getMessage();// ...返回錯誤響應
}

六、原理深度解析

1. 實現原理

@ControllerAdvice的工作原理:

  1. 通過@ControllerAdvice標記的類會被ExceptionHandlerExceptionResolver識別
  2. Spring初始化時會收集所有@ExceptionHandler方法
  3. 當控制器拋出異常時,DispatcherServlet會:
    • 查找當前控制器內的@ExceptionHandler方法
    • 如果沒有,則查找@ControllerAdvice中的處理方法
    • 按異常類型匹配最具體的方法

2. 核心組件協作

[DispatcherServlet]|v
[HandlerExceptionResolver]||-- [ExceptionHandlerExceptionResolver] (處理@ExceptionHandler)|-- [ResponseStatusExceptionResolver] (處理@ResponseStatus)`-- [DefaultHandlerExceptionResolver] (處理Spring標準異常)

3. 執行順序

  1. @ExceptionHandler方法(當前控制器內)
  2. @ControllerAdvice中的@ExceptionHandler方法
  3. @ResponseStatus異常
  4. Spring默認異常處理

七、常見問題解決方案

1. 異常處理不生效

可能原因:

  • 未啟用注解驅動:確保配置了@EnableWebMvc<mvc:annotation-driven/>
  • 包掃描問題:@ControllerAdvice類未被Spring管理
  • 異常被捕獲:上游代碼已經catch了異常

2. 處理多個相同類型異常

@ExceptionHandler({IllegalArgumentException.class, IllegalStateException.class})
public ResponseEntity<?> handleIllegal(RuntimeException ex) {// 統一處理多種相似異常
}

3. 自定義異常解析器

如需更復雜控制,可以實現HandlerExceptionResolver

@Component
public class CustomExceptionResolver implements HandlerExceptionResolver {@Overridepublic ModelAndView resolveException(HttpServletRequest request,HttpServletResponse response,Object handler,Exception ex) {// 自定義異常處理邏輯return ...;}
}

八、Spring Boot增強支持

1. 錯誤屬性配置

application.properties:

server.error.include-message=always
server.error.include-stacktrace=on_param
server.error.include-binding-errors=always

2. 自定義ErrorController

@Controller
@RequestMapping("${server.error.path:${error.path:/error}}")
public class CustomErrorController implements ErrorController {@RequestMappingpublic ResponseEntity<ErrorResponse> handleError(HttpServletRequest request) {HttpStatus status = getStatus(request);ErrorResponse error = new ErrorResponse(status.value(),"自定義錯誤處理",(String)request.getAttribute("javax.servlet.error.message"));return new ResponseEntity<>(error, status);}private HttpStatus getStatus(HttpServletRequest request) {Integer code = (Integer) request.getAttribute("javax.servlet.error.status_code");return code != null ? HttpStatus.valueOf(code) : HttpStatus.INTERNAL_SERVER_ERROR;}
}

九、性能優化建議

  1. 減少@ControllerAdvice掃描范圍:精確指定basePackages
  2. 避免在異常處理中進行IO操作:如數據庫寫入
  3. 使用響應緩存:對相同異常返回緩存響應
  4. 異步異常處理:對耗時處理使用@Async
@ExceptionHandler(ReportableException.class)
@Async
public CompletableFuture<ResponseEntity<?>> handleReportable(ReportableException ex) {// 異步處理可報告異常reportService.sendReport(ex);return CompletableFuture.completedFuture(ResponseEntity.badRequest().build());
}

通過合理使用@ControllerAdvice進行全局異常處理,可以顯著提高Spring應用的健壯性和可維護性,同時為客戶端提供一致的錯誤響應格式。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/903414.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/903414.shtml
英文地址,請注明出處:http://en.pswp.cn/news/903414.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

開放平臺架構方案- GraphQL 詳細解釋

GraphQL 詳細解釋 GraphQL 是一種用于 API 的查詢語言&#xff0c;由 Facebook 開發并開源&#xff0c;旨在提供一種更高效、靈活且強大的數據獲取和操作方式。它與傳統的 REST API 有顯著不同&#xff0c;通過類型系統和靈活的查詢能力&#xff0c;解決了 REST 中常見的過度獲…

labview項目文件架構

為了使 LabVIEW 項目更具可擴展性和易于維護&#xff0c;合理規劃和設計項目文件結構是非常重要的。 以下是一些基于行業經驗和最佳實踐的建議&#xff1a; 1. ### 文件夾層次劃分 將不同的功能模塊分開存儲在一個清晰的分層目錄結構中是一個常見的做法。通常情況下&#xff…

Chrome的插件擴展程序安裝目錄是什么?在哪個文件夾?

目錄 前提 直接復制到瀏覽器中打開 Mac下Chrome extension 安裝路徑 最近換了mac pro用起來雖然方便&#xff0c;但是對常用的一些使用方法還是不熟悉。這不為了找到mac上chrome插件的安裝路徑在哪里&#xff0c;花費了不少時間。我想應用有不少像小編一樣剛剛使用mac的小白…

第13講:圖形尺寸與分辨率設置——適配論文版面,打造專業圖稿!

目錄 ?? 為什么這一講重要? ?? 一、先認識幾個關鍵詞 ?? 二、ggsave() 是導出圖的標準方法 ?? 三、尺寸設置技巧:對齊目標期刊 ?? 找到目標期刊的圖形欄寬 ?? 四、多個圖組合導出(與 patchwork 搭配) ?? 五、使用 Cairo / ragg 導出高質量圖 ?? 六…

2025年- H13-Lc120-189.輪轉數組(普通數組)---java版

1.題目描述 2.思路 import java.util.Arrays;public class H189 {public static void main(String[] args) {int[] newArr {1, 2, 3, 4, 5};int[] nums new int[5];System.arraycopy(newArr,0,nums,0,4);System.out.println(Arrays.toString(nums)); } }補充2&#xff1a; 3.…

機器人--相機

教程 畸變和校正 單目和雙目標定 單雙&#xff0c;rgb-d原理 單目相機 只有一個攝像頭的相機。 原理 小孔成像。 缺點 單目相機無法測量物體點的深度信。 因為物體的Z軸坐標系無法測量。 雙目相機 有兩個攝像頭的相機。 用兩個單目相機組成的雙目相機就可以測量深度信…

Go 語言入門:(一) 環境安裝

一、前言 這里不同于其他人的 Go 語言入門&#xff0c;環境安裝我向來注重配置&#xff0c;比如依賴包、緩存的默認目錄。因為前期不弄好&#xff0c;后面要整理又影響這影響那的&#xff0c;所以就干脆寫成文章&#xff0c;方便后期撿起。 二、安裝 1. 安裝包 https://go.…

筆試專題(十二)

文章目錄 主持人調度題解代碼 小紅的ABC題解代碼 不相鄰取數題解代碼 空調遙控題解代碼 主持人調度 題目鏈接 題解 1. 排序 2. 先按左端點的大小進行排序&#xff0c;保證時間是連續的&#xff0c;如果后一個點的左端點大于等于前一個點的右端點就是和法的&#xff0c;否則…

Ansible 守護 Windows 安全(Ansible Safeguards Windows Security)

Ansible 守護 Windows 安全&#xff1a;自動化基線檢查與加固 在當今網絡威脅日益嚴峻的形勢下&#xff0c;保障 Windows 系統安全至關重要。Ansible 作為一款強大的自動化運維工具&#xff0c;可通過自動化腳本實現 Windows 安全基線檢查和加固&#xff0c;大幅提升運維效率并…

深度解析 MyBatis`@TableField(typeHandler = JacksonTypeHandler.class)`:優雅處理復雜數據存儲

一、引言&#xff1a;當Java對象遇見數據庫 在現代應用開發中&#xff0c;我們經常面臨一個關鍵問題&#xff1a;如何將復雜的Java對象&#xff08;如Map、List或自定義POJO&#xff09;優雅地存儲到關系型數據庫中&#xff1f;傳統解決方案需要開發者手動進行序列化和反序列化…

【無標題】四色定理研究團隊的構建與實施路徑——跨學科建模、編程與理論拓展的全流程方案

### **四色定理研究團隊的構建與實施路徑** **——跨學科建模、編程與理論拓展的全流程方案** --- #### **一、團隊構建與核心分工** ##### **1.1 核心角色與技能需求** | **角色** | **職責** | **技能要求** …

SQLMesh增量模型實戰指南:時間范圍分區

引言 在數據工程領域&#xff0c;處理大規模數據集和高頻率數據更新是一項挑戰。SQLMesh作為一款強大的數據編排工具&#xff0c;提供了增量模型功能&#xff0c;幫助數據工程師高效地管理和更新數據。本文將詳細介紹如何使用SQLMesh創建和管理基于時間范圍的增量模型&#xf…

TCP vs UDP:核心區別、握手過程與應用場景(附對比圖)

&#x1f310; 引言 在網絡通信中&#xff0c;TCP&#xff08;傳輸控制協議&#xff09;和UDP&#xff08;用戶數據報協議&#xff09;是兩大核心傳輸層協議。它們各有優劣&#xff0c;適用于不同場景。本文將用圖文對比實戰示例&#xff0c;幫你徹底理解兩者的區別&#xff0…

STM32F103C8T6信息

STM32F103C8T6 完整參數列表 一、核心參數 內核架構? ARM Cortex-M3 32位RISC處理器 最大主頻&#xff1a;72 MHz&#xff08;基于APB總線時鐘&#xff09; 運算性能&#xff1a;1.25 DMIPS/MHz&#xff08;Dhrystone 2.1基準&#xff09; 總線與存儲? 總線寬度&#xff…

WPF-遵循MVVM框架創建圖表的顯示【保姆級】

文章速覽 1、技術棧實現步驟1、創建WPF工程項目2、引入框架 Caliburn.Micro、數據可視化庫ScottPlot.WPF3、創建文件夾&#xff0c;并創建相應的View & ViewModel4、創建啟動類5、將啟動類設置為啟動項6、編寫View7、編寫VM8、將VM和View中的圖表進行綁定9、備注 示例效果 …

kafka理論學習匯總

基礎知識 基本簡介 Kafka 是一個分布式流式處理平臺&#xff0c;是一種分布式的&#xff0c;基于發布/訂閱的消息系統。 Kafka特點&#xff1a; 1. 同時為發布和訂閱提供高吞吐量 Kafka 的設計目標是以時間復雜度為 O(1) 的方式提供消息持久化能力&#xff0c;即使對 TB 級以…

【亞馬遜云】AWS Wavelength 從理論講解到實驗演練

&#x1faaa; 本文作者&#xff1a;許業寶 ?? 作者信息&#xff1a; &#x1f31e; VSTECS 云解決方案架構師 &#xff5c; AWS Ambassador &#xff5c; &#x1faaa; AWS Community Builder | 亞馬遜云科技技能云博主 ? 已獲六項 AWS 認證 | CKA、CKS認證 &#xff5c; …

ORACLE DATAGUARD遇到GAP增量恢復方式修復RAC環境備機的實踐

ORACLE DATAGUARD技術是一個常用的數據保護機制&#xff0c;在DATAGUARD運行過程中&#xff0c;遇到異常導致備機不同步&#xff0c;而主庫的歸檔日志也被清理&#xff0c;此時出現GAP&#xff0c;無法同步&#xff1b;就需要人工處理&#xff1b;對于小型數據庫重新全量同步數…

Java24 抗量子加密:后量子時代的安全基石

一、量子計算威脅與 Java 的應對 隨著量子計算機的快速發展&#xff0c;傳統加密算法面臨前所未有的挑戰。Shor 算法可在多項式時間內破解 RSA、ECC 等公鑰加密體系&#xff0c;而 Grover 算法能將對稱加密的暴力破解效率提升至平方根級別。據 NIST 預測&#xff0c;具備實用價…

day005

文章目錄 1. Linux系統核心文件1.1 查看系統版本信息1.1.1 /etc/os-release1.1.2 hostnamectl 1.2 查看主機名并修改1.2.1 hostname1.2.2 cat /etc/hostname1.2.3 hostnamectl 1.3 查看Linux內核版本1.3.1 uname -r1.3.2 hostnamectl 1.4 查看網卡信息并修改1.4.1 nmtui 網絡管…