1. 概述
本快速教程將介紹如何在 Spring Rest Controller 中訪問 HTTP Headers。
首先,我們將使用 @RequestHeader 註解分別讀取和讀取所有 HTTP Headers。
之後,我們將更深入地研究 @RequestHeader 的屬性。
2. 訪問 HTTP Headers
This section explains how to access HTTP headers, which contain metadata about HTTP requests and responses. HTTP headers are crucial for various tasks, including debugging, caching, and authentication.
What are HTTP Headers?
HTTP headers are key-value pairs that are sent along with HTTP requests and responses. They provide information such as:
- Content-Type: Specifies the type of content being transmitted (e.g.,
text/html,application/json). - Content-Length: Indicates the size of the response body in bytes.
- Cache-Control: Controls caching behavior by the browser or intermediary servers.
- Authorization: Contains authentication credentials.
- User-Agent: Identifies the client making the request.
Accessing HTTP Headers
There are several ways to access HTTP headers, depending on the programming language or tool you are using. Here are some common methods:
- In a Web Browser: You can view HTTP headers in your browser's developer tools (usually accessed by pressing F12). Look for the "Network" tab to inspect the headers of each request and response.
- Using a Command-Line Tool (e.g.,
curl): The-Ioption withcurlretrieves only the headers:curl -I <URL> - Programmatically (Example in Python):
import requests
response = requests.get("https://www.example.com")
headers = response.headers
print(headers)
# Example output:
# {'Content-Type': 'text/html; charset=UTF-8', 'Content-Length': '1234', 'Date': 'Wed, 15 Jun 2023 12:00:00 GMT', ...}
This example demonstrates how to use the requests library to fetch a response and access the headers. The response.headers attribute provides a dictionary-like object containing all the headers.
2.1. 單獨使用
如果需要訪問特定的請求頭,可以使用 @RequestHeader 註解,並指定請求頭的名稱:
@GetMapping("/greeting")
public ResponseEntity<String> greeting(@RequestHeader(HttpHeaders.ACCEPT_LANGUAGE) String language) {
// code that uses the language variable
return new ResponseEntity<String>(greeting, HttpStatus.OK);
}然後我們可以使用傳遞到方法的變量來訪問該值。如果請求中未找到名為 accept-language 的標頭,則該方法返回“400 Bad Request”錯誤。
我們的標頭不必是字符串。如果知道我們的標頭是數字,則可以將變量聲明為數字類型:
@GetMapping("/double")
public ResponseEntity<String> doubleNumber(@RequestHeader("my-number") int myNumber) {
return new ResponseEntity<String>(String.format("%d * 2 = %d",
myNumber, (myNumber * 2)), HttpStatus.OK);
}2.2. 一次性獲取所有請求頭
如果無法確定哪些請求頭將會存在,或者我們需要比我們方法簽名中期望的更多,我們可以使用 @RequestHeader 註解而無需指定名稱。
我們有幾個選項可以選擇變量類型:一個 Map、一個 MultiValueMap,或者一個 HttpHeaders 對象。
首先,讓我們將請求頭作為 Map 獲取:
@GetMapping("/listHeaders")
public ResponseEntity<String> listAllHeaders(
@RequestHeader Map<String, String> headers) {
headers.forEach((key, value) -> {
LOG.info(String.format("Header '%s' = %s", key, value));
});
return new ResponseEntity<String>(
String.format("Listed %d headers", headers.size()), HttpStatus.OK);
}如果使用 Map 並且其中一個標題包含多個值,我們只會獲取第一個值。 這相當於在 MultiValueMap 上調用 getFirst 方法。
如果我們的標題可能包含多個值,我們可以將其獲取為 MultiValueMap。
@GetMapping("/multiValue")
public ResponseEntity<String> multiValue(
@RequestHeader MultiValueMap<String, String> headers) {
headers.forEach((key, value) -> {
LOG.info(String.format(
"Header '%s' = %s", key, value.stream().collect(Collectors.joining("|"))));
});
return new ResponseEntity<String>(
String.format("Listed %d headers", headers.size()), HttpStatus.OK);
}我們還可以將我們的頭部信息獲取為 HttpHeaders 對象:
@GetMapping("/getBaseUrl")
public ResponseEntity<String> getBaseUrl(@RequestHeader HttpHeaders headers) {
InetSocketAddress host = headers.getHost();
String url = "http://" + host.getHostName() + ":" + host.getPort();
return new ResponseEntity<String>(String.format("Base URL = %s", url), HttpStatus.OK);
}HttpHeaders 對象提供對常見應用程序頭部的訪問器。
當我們通過名稱從 Map、MultiValueMap 或 HttpHeaders 對象訪問一個頭,如果該頭不存在,將會返回 null。
3. <em @RequestHeader 屬性詳解
現在我們已經瞭解了使用 註解訪問請求頭的基本方法,接下來我們更深入地瞭解其屬性。
我們已經在指定請求頭名稱時,隱式使用了 或 屬性:
public ResponseEntity<String> greeting(@RequestHeader(HttpHeaders.ACCEPT_LANGUAGE) String language) {}我們可以通過使用 name 屬性來實現相同的結果:
public ResponseEntity<String> greeting(
@RequestHeader(name = HttpHeaders.ACCEPT_LANGUAGE) String language) {}接下來,讓我們完全相同地使用 屬性:
public ResponseEntity<String> greeting(
@RequestHeader(value = HttpHeaders.ACCEPT_LANGUAGE) String language) {}當我們為標題指定名稱時,標題默認必須存在。如果請求中未找到該標題,控制器將返回 400 錯誤。
我們使用 required 屬性來指示我們的標題並非必需:
@GetMapping("/nonRequiredHeader")
public ResponseEntity<String> evaluateNonRequiredHeader(
@RequestHeader(value = "optional-header", required = false) String optionalHeader) {
return new ResponseEntity<String>(String.format(
"Was the optional header present? %s!",
(optionalHeader == null ? "No" : "Yes")),HttpStatus.OK);
}由於我們的變量在請求中未包含時將為 null,因此我們需要確保進行適當的 null 檢查。
讓我們使用 defaultValue 屬性為我們的標題提供默認值:
@GetMapping("/default")
public ResponseEntity<String> evaluateDefaultHeaderValue(
@RequestHeader(value = "optional-header", defaultValue = "3600") int optionalHeader) {
return new ResponseEntity<String>(
String.format("Optional Header is %d", optionalHeader), HttpStatus.OK);
}4. 結論
在本簡短教程中,我們學習瞭如何在 Spring REST 控制器中訪問請求頭。
首先,我們使用 @RequestHeader 註解為控制器的方法提供請求頭。
在瞭解了基本內容之後,我們對 @RequestHeader 註解的屬性進行了詳細分析。