1. 引言
使用 Spring,我們通常有多種方式可以實現相同的目標,包括微調 HTTP 響應。
在本簡短教程中,我們將學習如何使用 <em >ResponseEntity</em> 設置 HTTP 響應的 body、狀態碼和 headers。
2. ResponseEntity
ResponseEntity 代表完整的 HTTP 響應:狀態碼、頭部和正文。因此,我們可以使用它來完全配置 HTTP 響應。
如果我們想使用它,我們需要從端點返回它;Spring 會負責其餘部分。
ResponseEntity 是一種泛型類型。因此,我們可以使用任何類型作為響應正文:
@GetMapping("/hello")
ResponseEntity<String> hello() {
return new ResponseEntity<>("Hello World!", HttpStatus.OK);
}由於我們通過編程方式指定響應狀態,因此可以針對不同的場景返回不同的狀態碼:
@GetMapping("/age")
ResponseEntity<String> age(
@RequestParam("yearOfBirth") int yearOfBirth) {
if (isInFuture(yearOfBirth)) {
return new ResponseEntity<>(
"Year of birth cannot be in the future",
HttpStatus.BAD_REQUEST);
}
return new ResponseEntity<>(
"Your age is " + calculateAge(yearOfBirth),
HttpStatus.OK);
}此外,我們還可以設置 HTTP 頭部:
@GetMapping("/customHeader")
ResponseEntity<String> customHeader() {
HttpHeaders headers = new HttpHeaders();
headers.add("Custom-Header", "foo");
return new ResponseEntity<>(
"Custom header set", headers, HttpStatus.OK);
}此外,ResponseEntity提供兩個嵌套的構建器接口:HeadersBuilder和它的子接口,BodyBuilder。因此,我們可以通過ResponseEntity的靜態方法訪問它們的各項功能。
最簡單的場景是帶有響應體和 HTTP 200 響應碼的響應:
@GetMapping("/hello")
ResponseEntity<String> hello() {
return ResponseEntity.ok("Hello World!");
}對於最常用的 HTTP 狀態碼,我們提供靜態方法:
BodyBuilder accepted();
BodyBuilder badRequest();
BodyBuilder created(java.net.URI location);
HeadersBuilder<?> noContent();
HeadersBuilder<?> notFound();
BodyBuilder ok();此外,我們還可以使用 BodyBuilder status(HttpStatus status) 和 BodyBuilder status(int status) 方法來設置任何 HTTP 狀態碼。
最後,通過 ResponseEntity<T> BodyBuilder.body(T body),我們可以設置 HTTP 響應體:
@GetMapping("/age")
ResponseEntity<String> age(@RequestParam("yearOfBirth") int yearOfBirth) {
if (isInFuture(yearOfBirth)) {
return ResponseEntity.badRequest()
.body("Year of birth cannot be in the future");
}
return ResponseEntity.status(HttpStatus.OK)
.body("Your age is " + calculateAge(yearOfBirth));
}我們還可以設置自定義頭部:
@GetMapping("/customHeader")
ResponseEntity<String> customHeader() {
return ResponseEntity.ok()
.header("Custom-Header", "foo")
.body("Custom header set");
}由於BodyBuilder.body()返回ResponseEntity而不是BodyBuilder,因此它應該是最後一次調用。
請注意,使用HeaderBuilder無法設置響應體中的任何屬性。
在從控制器返回ResponseEntity<T> 對象時,我們可能會在處理請求時遇到異常或錯誤,並且希望以其他類型(例如 E)返回與錯誤相關的信息,以便呈現給用户。
Spring 3.2 引入了全局@ExceptionHandler支持,以及新的@ControllerAdvice註解,用於處理此類場景。有關更詳細的信息,請參閲我們的現有文章 [此處]。
雖然ResponseEntity功能強大,但我們不應過度使用它。 在簡單情況下,有其他選項可以滿足我們的需求,併產生更簡潔的代碼。
3. 替代方案
以下是一些替代方案,您可以根據您的具體需求進行選擇:
- 方案 A: 採用更廣泛的解決方案,以應對潛在的風險。
- 方案 B: 實施更精簡的策略,以降低運營成本。
- 方案 C: 結合方案 A 和方案 B 的優點,實現最佳效果。
為了更好地理解這些方案,請參考以下詳細説明:
- 方案 A 詳細説明: 此方案旨在提供更全面的覆蓋範圍,從而最大限度地減少潛在的失敗風險。它包括額外的安全措施、冗餘系統和全面的測試計劃。
- 方案 B 詳細説明: 此方案側重於效率和成本效益。它通過自動化、優化流程和減少不必要的資源來降低運營成本。
- 方案 C 詳細説明: 方案 C 結合了方案 A 和方案 B 的優勢。它既提供了強大的風險管理能力,又保持了成本效益。
請選擇最適合您需求的方案。如果您有任何疑問,請隨時聯繫我們的技術支持團隊。
3.1. <em @ResponseBody</em>>
在經典的 Spring MVC 應用中,端點通常返回渲染後的 HTML 頁面。有時我們只需要返回實際的數據,例如,當我們使用該端點與 AJAX 進行交互時。
在這種情況下,我們可以將請求處理方法標記為 <em @ResponseBody</em>>,Spring 會將該方法的結果值視為 HTTP 響應體的本身。
獲取更多信息,這篇文章是一個不錯的起點。
3.2. <em @ResponseStatus</em>
當端點成功返回時,Spring 提供 HTTP 200 (OK) 響應。如果端點拋出異常,Spring 會查找異常處理器,以確定應使用哪個 HTTP 狀態碼。
我們可以使用 @ResponseStatus 標記這些方法,因此 Spring 會返回帶有自定義 HTTP 狀態碼。
欲瞭解更多示例,請訪問我們關於自定義狀態碼的文章。
3.3. 直接操控響應
Spring 也允許我們直接訪問 jakarta.servlet.http.HttpServletResponse 對象;我們只需將其聲明為方法參數即可:
@GetMapping("/manual")
void manual(HttpServletResponse response) throws IOException {
response.setHeader("Custom-Header", "foo");
response.setStatus(200);
response.getWriter().println("Hello World!");
}由於 Spring 提供在底層實現之上抽象和額外的能力,因此不應通過這種方式處理響應。
4. 結論
在本文中,我們探討了多種方法來操縱 Spring 中的 HTTP 響應,並分析了它們的優缺點。