Spring Boot HTTP狀態碼完全指南:從入門到精通
前言
在RESTful API開發中,HTTP狀態碼是與客戶端通信的重要橋梁。Spring Boot通過HttpStatus
枚舉提供了完整的HTTP狀態碼支持。本文將深入解析這些狀態碼的含義、使用場景以及在Spring Boot中的最佳實踐。
1. 信息響應 (100-199) - 請求處理中
1.1 CONTINUE (100)
- 含義:客戶端應繼續發送請求的剩余部分
- 使用場景:當客戶端發送Expect: 100-continue頭時,服務器確認可以接收請求體
- Spring Boot示例:大文件上傳時的預檢確認
1.2 SWITCHING_PROTOCOLS (101)
- 含義:服務器同意客戶端請求,切換協議
- 使用場景:WebSocket連接升級、HTTP/2協議切換
1.3 PROCESSING (102)
- 含義:服務器已收到請求,正在處理但尚未完成
- 使用場景:長時間運行的操作,如大數據處理
1.4 EARLY_HINTS (103)
- 含義:用于在最終響應之前發送一些HTTP頭
- 使用場景:預加載資源,優化頁面加載性能
2. 成功響應 (200-299) - 請求成功處理
2.1 OK (200) ?
- 含義:請求成功
- 使用場景:GET請求成功返回數據
- Spring Boot示例:
@GetMapping("/users/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {User user = userService.findById(id);return ResponseEntity.ok(user); // 返回200狀態碼
}
2.2 CREATED (201) 🆕
- 含義:資源創建成功
- 使用場景:POST請求創建新資源
- 最佳實踐:應在響應頭中包含新資源的Location
@PostMapping("/users")
public ResponseEntity<User> createUser(@RequestBody User user) {User savedUser = userService.save(user);return ResponseEntity.created(URI.create("/users/" + savedUser.getId())).body(savedUser);
}
2.3 ACCEPTED (202) ?
- 含義:請求已接受,但處理尚未完成
- 使用場景:異步操作,如批量處理、郵件發送
2.4 NO_CONTENT (204) 🚫
- 含義:請求成功,但無內容返回
- 使用場景:DELETE操作成功、UPDATE操作無需返回數據
@DeleteMapping("/users/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {userService.deleteById(id);return ResponseEntity.noContent().build(); // 返回204
}
2.5 PARTIAL_CONTENT (206) 📦
- 含義:部分內容請求成功
- 使用場景:分片下載、斷點續傳
3. 重定向響應 (300-399) - 需要進一步操作
3.1 MOVED_PERMANENTLY (301) 🔄
- 含義:資源已永久移動到新位置
- 使用場景:網站改版、API版本遷移
3.2 FOUND (302) 🔍
- 含義:資源臨時移動到其他位置
- 使用場景:臨時重定向,如登錄后跳轉
3.3 SEE_OTHER (303) 👀
- 含義:查看其他URI獲取響應
- 使用場景:POST成功后重定向到GET請求
3.4 NOT_MODIFIED (304) 📄
- 含義:資源未修改,可使用緩存版本
- 使用場景:配合If-Modified-Since或ETag使用
4. 客戶端錯誤 (400-499) - 客戶端請求有問題
4.1 BAD_REQUEST (400) ?
- 含義:請求語法錯誤或參數無效
- 使用場景:參數驗證失敗、JSON格式錯誤
- Spring Boot驗證示例:
@PostMapping("/users")
public ResponseEntity<?> createUser(@Valid @RequestBody UserCreateRequest request) {// 自動驗證,失敗返回400userService.create(request);return ResponseEntity.ok().build();
}
4.2 UNAUTHORIZED (401) 🔐
- 含義:需要身份驗證
- 使用場景:未提供認證信息或認證失敗
4.3 FORBIDDEN (403) ??
- 含義:服務器理解請求但拒絕執行
- 使用場景:權限不足、IP限制
4.4 NOT_FOUND (404) 🔍
- 含義:請求的資源不存在
- 使用場景:訪問不存在的URL或資源ID
@GetMapping("/users/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {return userService.findById(id).map(ResponseEntity::ok).orElse(ResponseEntity.notFound().build()); // 返回404
}
4.5 METHOD_NOT_ALLOWED (405) 🚷
- 含義:請求方法不被允許
- 使用場景:對只讀資源執行POST操作
4.6 UNPROCESSABLE_ENTITY (422) 📝
- 含義:請求格式正確但語義錯誤
- 使用場景:業務規則驗證失敗,如郵箱已注冊
4.7 TOO_MANY_REQUESTS (429) 🚦
- 含義:請求頻率過高
- 使用場景:API限流、防刷機制
5. 服務器錯誤 (500-599) - 服務器處理失敗
5.1 INTERNAL_SERVER_ERROR (500) 💥
- 含義:服務器內部錯誤
- 使用場景:未捕獲的異常、數據庫連接失敗
- Spring Boot異常處理:
@RestControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(Exception.class)public ResponseEntity<ApiResponse<?>> handleException(Exception e) {log.error("服務器異常", e);return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(ApiResponse.error(500, "系統繁忙,請稍后重試"));}
}
5.2 NOT_IMPLEMENTED (501) 🔧
- 含義:服務器不支持請求的功能
- 使用場景:未實現的API端點
5.3 BAD_GATEWAY (502) 🌐
- 含義:網關或代理服務器從上游服務器收到無效響應
- 使用場景:微服務調用失敗
5.4 SERVICE_UNAVAILABLE (503) ?
- 含義:服務暫時不可用
- 使用場景:系統維護、過載保護
5.5 GATEWAY_TIMEOUT (504) ?
- 含義:網關超時
- 使用場景:上游服務響應超時
6. Spring Boot中的最佳實踐
6.1 使用ResponseEntity精確控制狀態碼
@GetMapping("/custom")
public ResponseEntity<String> customResponse() {if (someCondition) {return ResponseEntity.status(HttpStatus.CREATED).body("Created");} else {return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Not Found");}
}
6.2 統一的錯誤響應格式
@Data
public class ErrorResponse {private int status;private String error;private String message;private String path;private LocalDateTime timestamp;public ErrorResponse(HttpStatus status, String message, String path) {this.status = status.value();this.error = status.getReasonPhrase();this.message = message;this.path = path;this.timestamp = LocalDateTime.now();}
}
6.3 狀態碼選擇指南
操作類型 | 成功狀態碼 | 失敗狀態碼 |
---|---|---|
查詢(GET) | 200 OK | 404 Not Found |
創建(POST) | 201 Created | 400 Bad Request |
更新(PUT) | 200 OK | 404 Not Found |
刪除(DELETE) | 204 No Content | 404 Not Found |
部分更新(PATCH) | 200 OK | 400 Bad Request |
7. 常見問題解答
Q: 什么時候使用200 vs 204?
A: 當需要返回數據時用200,不需要返回數據時用204。
Q: 401和403的區別?
A: 401表示未認證(需要登錄),403表示已認證但權限不足。
Q: 400和422的區別?
A: 400表示請求語法錯誤,422表示語法正確但業務邏輯錯誤。
8. 總結
正確地使用HTTP狀態碼是構建高質量RESTful API的關鍵。Spring Boot的HttpStatus
枚舉為我們提供了完整的支持:
- 信息類狀態碼用于通信協商
- 成功類狀態碼表示操作成功
- 重定向類狀態碼處理資源位置變更
- 客戶端錯誤類狀態碼幫助客戶端糾正請求
- 服務器錯誤類狀態碼表示服務端問題
通過合理選擇狀態碼并提供清晰的錯誤信息,可以大大提升API的可用性和開發者體驗。
9. 完整HTTP狀態碼參考表格
以下是Spring Boot中HttpStatus
枚舉包含的所有狀態碼的完整參考表格:
狀態碼 | 枚舉常量 | 狀態系列 | 含義描述 | 使用場景 |
---|---|---|---|---|
100 | CONTINUE | INFORMATIONAL | 繼續 | 客戶端應繼續發送請求的剩余部分 |
101 | SWITCHING_PROTOCOLS | INFORMATIONAL | 切換協議 | WebSocket連接升級、HTTP/2協議切換 |
102 | PROCESSING | INFORMATIONAL | 處理中 | 長時間運行的操作,如大數據處理 |
103 | EARLY_HINTS | INFORMATIONAL | 早期提示 | 預加載資源,優化頁面加載性能 |
103 | CHECKPOINT | INFORMATIONAL | 檢查點(已棄用) | 已棄用,使用EARLY_HINTS替代 |
200 | OK | SUCCESSFUL | 成功 | GET請求成功返回數據 |
201 | CREATED | SUCCESSFUL | 已創建 | POST請求創建新資源 |
202 | ACCEPTED | SUCCESSFUL | 已接受 | 異步操作,如批量處理 |
203 | NON_AUTHORITATIVE_INFORMATION | SUCCESSFUL | 非權威信息 | 代理服務器修改了響應 |
204 | NO_CONTENT | SUCCESSFUL | 無內容 | DELETE操作成功、UPDATE操作無需返回數據 |
205 | RESET_CONTENT | SUCCESSFUL | 重置內容 | 客戶端需要重置文檔視圖 |
206 | PARTIAL_CONTENT | SUCCESSFUL | 部分內容 | 分片下載、斷點續傳 |
207 | MULTI_STATUS | SUCCESSFUL | 多狀態 | WebDAV擴展,多個操作狀態 |
208 | ALREADY_REPORTED | SUCCESSFUL | 已報告 | WebDAV,成員已在之前報告中 |
226 | IM_USED | SUCCESSFUL | IM已使用 | 服務器已對請求進行了實例操作 |
300 | MULTIPLE_CHOICES | REDIRECTION | 多種選擇 | 請求的資源有多個表示形式 |
301 | MOVED_PERMANENTLY | REDIRECTION | 永久移動 | 資源已永久移動到新位置 |
302 | FOUND | REDIRECTION | 臨時移動 | 資源臨時移動到其他位置 |
302 | MOVED_TEMPORARILY | REDIRECTION | 臨時移動(已棄用) | 已棄用,使用FOUND替代 |
303 | SEE_OTHER | REDIRECTION | 查看其他 | POST成功后重定向到GET請求 |
304 | NOT_MODIFIED | REDIRECTION | 未修改 | 資源未修改,可使用緩存版本 |
305 | USE_PROXY | REDIRECTION | 使用代理(已棄用) | 已棄用 |
307 | TEMPORARY_REDIRECT | REDIRECTION | 臨時重定向 | 請求應使用另一個URI重復 |
308 | PERMANENT_REDIRECT | REDIRECTION | 永久重定向 | 請求和所有未來請求應使用另一個URI |
400 | BAD_REQUEST | CLIENT_ERROR | 錯誤請求 | 請求語法錯誤或參數無效 |
401 | UNAUTHORIZED | CLIENT_ERROR | 未授權 | 需要身份驗證 |
402 | PAYMENT_REQUIRED | CLIENT_ERROR | 需要付款 | 保留用于未來支付系統 |
403 | FORBIDDEN | CLIENT_ERROR | 禁止訪問 | 權限不足、IP限制 |
404 | NOT_FOUND | CLIENT_ERROR | 未找到 | 請求的資源不存在 |
405 | METHOD_NOT_ALLOWED | CLIENT_ERROR | 方法不允許 | 請求方法不被允許 |
406 | NOT_ACCEPTABLE | CLIENT_ERROR | 不可接受 | 服務器無法生成客戶端接受的內容 |
407 | PROXY_AUTHENTICATION_REQUIRED | CLIENT_ERROR | 需要代理認證 | 代理服務器需要認證 |
408 | REQUEST_TIMEOUT | CLIENT_ERROR | 請求超時 | 服務器等待請求超時 |
409 | CONFLICT | CLIENT_ERROR | 沖突 | 請求與當前資源狀態沖突 |
410 | GONE | CLIENT_ERROR | 已刪除 | 資源已永久刪除 |
411 | LENGTH_REQUIRED | CLIENT_ERROR | 需要長度 | 需要Content-Length頭 |
412 | PRECONDITION_FAILED | CLIENT_ERROR | 前提條件失敗 | 請求頭中前提條件失敗 |
413 | PAYLOAD_TOO_LARGE | CLIENT_ERROR | 負載過大 | 請求實體過大 |
413 | REQUEST_ENTITY_TOO_LARGE | CLIENT_ERROR | 請求實體過大(已棄用) | 已棄用,使用PAYLOAD_TOO_LARGE |
414 | URI_TOO_LONG | CLIENT_ERROR | URI過長 | 請求URI過長 |
414 | REQUEST_URI_TOO_LONG | CLIENT_ERROR | 請求URI過長(已棄用) | 已棄用,使用URI_TOO_LONG |
415 | UNSUPPORTED_MEDIA_TYPE | CLIENT_ERROR | 不支持的媒體類型 | 不支持的媒體格式 |
416 | REQUESTED_RANGE_NOT_SATISFIABLE | CLIENT_ERROR | 請求范圍不可滿足 | 無法滿足請求的范圍 |
417 | EXPECTATION_FAILED | CLIENT_ERROR | 期望失敗 | 無法滿足Expect請求頭 |
418 | I_AM_A_TEAPOT | CLIENT_ERROR | 我是茶壺 | HTTP愚人節笑話,實際不使用 |
419 | INSUFFICIENT_SPACE_ON_RESOURCE | CLIENT_ERROR | 資源空間不足(已棄用) | 已棄用 |
420 | METHOD_FAILURE | CLIENT_ERROR | 方法失敗(已棄用) | 已棄用 |
421 | DESTINATION_LOCKED | CLIENT_ERROR | 目標鎖定(已棄用) | 已棄用 |
422 | UNPROCESSABLE_ENTITY | CLIENT_ERROR | 不可處理的實體 | 請求格式正確但語義錯誤 |
423 | LOCKED | CLIENT_ERROR | 已鎖定 | 資源被鎖定 |
424 | FAILED_DEPENDENCY | CLIENT_ERROR | 依賴失敗 | WebDAV,依賴的操作失敗 |
425 | TOO_EARLY | CLIENT_ERROR | 太早 | 服務器不愿意處理可能重放的請求 |
426 | UPGRADE_REQUIRED | CLIENT_ERROR | 需要升級 | 客戶端應切換到不同的協議 |
428 | PRECONDITION_REQUIRED | CLIENT_ERROR | 需要前提條件 | 需要條件性請求 |
429 | TOO_MANY_REQUESTS | CLIENT_ERROR | 請求過多 | API限流、防刷機制 |
431 | REQUEST_HEADER_FIELDS_TOO_LARGE | CLIENT_ERROR | 請求頭字段過大 | 請求頭字段太大 |
451 | UNAVAILABLE_FOR_LEGAL_REASONS | CLIENT_ERROR | 因法律原因不可用 | 因法律要求無法提供 |
500 | INTERNAL_SERVER_ERROR | SERVER_ERROR | 內部服務器錯誤 | 服務器內部錯誤 |
501 | NOT_IMPLEMENTED | SERVER_ERROR | 未實現 | 服務器不支持請求的功能 |
502 | BAD_GATEWAY | SERVER_ERROR | 錯誤網關 | 網關或代理服務器收到無效響應 |
503 | SERVICE_UNAVAILABLE | SERVER_ERROR | 服務不可用 | 系統維護、過載保護 |
504 | GATEWAY_TIMEOUT | SERVER_ERROR | 網關超時 | 上游服務響應超時 |
505 | HTTP_VERSION_NOT_SUPPORTED | SERVER_ERROR | HTTP版本不支持 | 不支持的HTTP協議版本 |
506 | VARIANT_ALSO_NEGOTIATES | SERVER_ERROR | 變體也可協商 | 透明內容協商中的循環引用 |
507 | INSUFFICIENT_STORAGE | SERVER_ERROR | 存儲空間不足 | WebDAV,存儲空間不足 |
508 | LOOP_DETECTED | SERVER_ERROR | 檢測到循環 | WebDAV,檢測到無限循環 |
509 | BANDWIDTH_LIMIT_EXCEEDED | SERVER_ERROR | 帶寬限制超出 | 帶寬使用超出限制 |
510 | NOT_EXTENDED | SERVER_ERROR | 未擴展 | 需要進一步擴展才能完成請求 |
511 | NETWORK_AUTHENTICATION_REQUIRED | SERVER_ERROR | 需要網絡認證 | 需要網絡認證才能訪問 |
表格說明:
-
狀態碼系列說明:
- INFORMATIONAL (100-199): 信息響應,請求處理中
- SUCCESSFUL (200-299): 成功響應,請求成功處理
- REDIRECTION (300-399): 重定向響應,需要進一步操作
- CLIENT_ERROR (400-499): 客戶端錯誤,客戶端請求有問題
- SERVER_ERROR (500-599): 服務器錯誤,服務器處理失敗
-
已棄用狀態碼: 表格中標記為"已棄用"的狀態碼不建議在新項目中使用
-
常用狀態碼: 在實際開發中,最常用的狀態碼包括:200, 201, 204, 400, 401, 403, 404, 500
希望本文能幫助您更好地理解和使用Spring Boot中的HTTP狀態碼。如有疑問,歡迎留言討論!