Spring Boot 3 中將 HttpStatus 遷移到 HttpStatusCode
1. 概述
在本文中,我們將了解如何在 Spring Boot 應用程式中使用HttpStatusCode
,重點是版本 3.3.3 中引入的最新增強功能。透過這些增強功能, HttpStatusCode
已合併到HttpStatus
實作中,簡化了我們使用 HTTP 狀態碼的方式。
這些改進的主要目的是提供一種更靈活、更可靠的方法來處理標準和自訂HTTP 狀態程式碼,為我們在處理HTTP 回應時提供更高的靈活性和可擴展性,同時保持向後相容性。
HttpStatus
枚舉器
在 Spring 3.3.3 之前,HTTP 狀態碼在HttpStatus.
這限制了自訂或非標準 HTTP 狀態代碼的使用,因為枚舉是一組固定的預定義值。
儘管HttpStatus
類別尚未被棄用,但一些傳回原始整數狀態碼的枚舉和方法(例如getRawStatusCode()
和rawStatusCode()
現已被棄用。儘管如此,使用@ResponseStatus
註解來提高程式碼可讀性仍然是建議的方法。
我們也可以將HttpStatus
與HttpStatusCode
結合使用,以實現更靈活的 HTTP 回應管理:
@GetMapping("/exception")
public ResponseEntity<String> resourceNotFound() {
HttpStatus statusCode = HttpStatus.NOT_FOUND;
if (statusCode.is4xxClientError()) {
return new ResponseEntity<>("Resource not found", HttpStatusCode.valueOf(404));
}
return new ResponseEntity<>("Resource found", HttpStatusCode.valueOf(200));
}
HttpStatusCode
接口
HttpStatusCode
介面旨在支援HttpStatus
中預先定義狀態碼以外的自訂狀態碼。它有8個實例方法:
-
is1xxInformational()
-
is2xxSuccessful()
-
is3xxRedirection()
-
is4xxClientError()
-
is5xxServerError()
-
isError()
-
isSameCodeAs(HttpStatusCode other)
-
value()
這些方法不僅增加了處理不同HTTP狀態的靈活性,而且簡化了檢查回應類別的流程,從而提高了狀態碼管理的清晰度和效率。
讓我們看一個如何在實踐中使用它們的範例:
@GetMapping("/resource")
public ResponseEntity successStatusCode() {
HttpStatusCode statusCode = HttpStatusCode.valueOf(200);
if (statusCode.is2xxSuccessful()) {
return new ResponseEntity("Success", statusCode);
}
return new ResponseEntity("Moved Permanently", HttpStatusCode.valueOf(301));
}
3.1.靜態方法valueOf(int)
此方法傳回給定int值的HttpStatusCode
物件。輸入參數必須是 3 位正數,否則我們會得到IllegalArgumentException
。
valueOf()
將狀態代碼對應到HttpStatus.
如果沒有現有條目與提供的狀態代碼匹配,則該方法預設傳回DefaultHttpStatusCode
的實例。
DefaultHttpStatusCode
類別實作HttpStatusCode
並提供value()
方法的簡單實現,該方法傳回用於初始化它的原始整數值。這種方法可確保所有 HTTP 狀態代碼(無論是自訂的還是非標準的)仍然易於使用:
@GetMapping("/custom-exception")
public ResponseEntity<String> goneStatusCode() {
throw new ResourceGoneException("Resource Gone", HttpStatusCode.valueOf(410));
}
4. 在自訂例外狀況中使用HttpStatusCode
接下來,讓我們看看如何在 ExceptionHandler 中使用帶有HttpStatusCode
的自訂例外狀況ExceptionHandler.
我們將使用@ControllerAdvice
註解來跨所有控制器全域處理異常,並使用@ExceptionHandler
註解來管理自訂異常的實例。
這種方法集中了 Spring MVC 應用程式中的錯誤處理,使程式碼更乾淨、更易於維護。
4.1. @ControllerAdvice
和@ExceptionHandler
@ControllerAdvice
全域處理異常,而@ExceptionHandler
管理自訂異常實例以傳回帶有異常訊息和狀態代碼的一致 HTTP 回應。
讓我們看看如何在實踐中使用這兩個註釋:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(CustomException.class)
public ResponseEntity<String> handleGoneException(CustomException e) {
return new ResponseEntity<>(e.getMessage(), e.getStatusCode());
}
}
4.2.自訂例外
接下來,讓我們定義一個CustomException
類,它擴展RuntimeException
並包含HttpStatusCode
字段,啟用自訂訊息和 HTTP 狀態碼以進行更精確的錯誤處理:
public class CustomException extends RuntimeException {
private final HttpStatusCode statusCode;
public CustomException(String message, HttpStatusCode statusCode) {
super(message);
this.statusCode = statusCode;
}
public HttpStatusCode getStatusCode() {
return statusCode;
}
}
5. 結論
HttpStatus
枚舉包含一組有限的標準 HTTP 狀態碼,這些程式碼在舊版的 Spring 中適用於大多數用例。然而,他們在定義自訂狀態代碼方面缺乏靈活性。
Spring Boot 3.3.3 引入了HttpStatusCode,
透過允許我們定義自訂狀態碼來解決此限制。這提供了一種更靈活的方式來處理 HTTP 狀態碼,並提供常用狀態碼的實例方法,例如is2xxSuccessful()
和is3xxRedirection(),
最終允許對回應處理進行更精細的控制。
與往常一樣,完整的程式碼以及本文中提供的所有範例都可以在 GitHub 上找到。