- Java 異常類
首先讓我們簡單瞭解或重新學習下 Java 的異常機制。
Java 內部的異常類 Throwable 包括了 Exception 和 Error 兩大類,所有的異常類都是 Object 物件。
Error 是不可捕捉的異常,通俗的說就是由於 Java 內部 JVM 引起的不可預見的異常, Java 虛擬機器會選擇終止執行緒。如 OutOfMemoryError ,就是 Java 虛擬機器執行過程中出現記憶體資源錯誤丟擲的。
Excetpion 異常是程式本身引起的,它又分為執行時異常 RuntimeException,和非執行時(編譯時)IOException 等異常。如除數為零時引發的 ArrayIndexOutOfBoundException 異常就是執行時異常。非執行異常都是可查可捕捉的。Java 編譯器會告訴程式他錯了,錯在哪裡,正確的建議什麼。我們可以透過 throws 配合 try-catch 來處理。
- Java 異常處理機制
在 Java 應用程式中,異常處理機制為:丟擲異常,捕捉異常。
丟擲異常:當一個方法出現錯誤引發異常時,方法建立異常物件並交付執行時系統,異常物件中包含異常型別和出現異常時的程式執行時資訊。執行時系統負責尋找處置異常的程式碼並執行。
捕獲異常:在方法丟擲異常之後,執行時系統將轉為尋找合適的異常處理器(Exception Handler)。潛在的異常處理器是異常發生時依次存留在呼叫棧中的方法的集合。
當異常處理器能處理的異常型別與方法丟擲的異常型別相符時,即為合適的異常處理器。執行時系統從發生異常的方法開始,依次回查呼叫棧中的方法,直至找到含有合適異常處理器的方法並執行。
當執行時系統遍歷呼叫棧而未找到合適 的異常處理器,則執行時系統終止。同時,意味著 Java 程式的終止。
- Spring Boot 異常處理
Spring Boot 的所有異常處理都基於 java 的。
在 Spring Boot 應用程式中,通常統一處理異常的方法有 使用註解處理 RestControllerAdvice
本示例主要目的處理我們日常 Spring Boot 中的異常處理
在 Web 專案中透過 ControllerAdvice、RestControllerAdvice 實現全域性異常處理
ControllerAdvice 和 RestControllerAdvice 的區別 相當於 Controller 和 RestController 的區別。
程式碼示例
- GlobalExceptionHandler.java
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler({Exception.class})
public Object exceptionHandler(Exception e){
Map<String,Object> map=new HashMap<>();
map.put("status",-1);
map.put("msg",e.getLocalizedMessage());
return map;
}
}
- 配置介紹
RestControllerAdvice:全域性捕獲異常,異常集中處理,更好的使業務邏輯與異常處理剝離開,定義在類上
ExceptionHandler:統一處理某一類異常,宣告該方法用於捕獲 value 所指的型別的異常(注意:當該異常的子父類都被宣告時,按照先子後父的順序進行捕獲)
ResponseStatus:將某種異常對映為 HTTP 狀態碼,可用在方法上,也可以用在類上(自定義執行時異常類)。
- HogwartsTestUserController.java
在 HogwartsTestUserController.java 新增一個 error 介面
/**
* 模擬丟擲異常
* */
@GetMapping("/error")
public Object err(){
throw new RuntimeException("丟擲一個異常");
}
GET http://127.0.0.1:8081/api/user/users/3 正常返回
{
"id": 3,
"name": "HogwartsTest2",
"pwd": "HogwartsTest2"
}
GET http://127.0.0.1:8081/api/user/error 丟擲異常,並給出提示資訊