1. 引言
<em>RestTemplate</em> 類是 Spring 中執行客户端 HTTP 操作的核心工具。它提供了用於構建 HTTP 請求和處理響應的多個實用方法。
由於 <em>RestTemplate</em> 與 Jackson 緊密集成,因此可以輕鬆地將大多數對象序列化/反序列化為 JSON,無需過多努力。但是,處理對象集合並非易事。
在本教程中,我們將學習如何使用 <em>RestTemplate</em> 來 GET 和 POST 對象列表。
2. 示例服務
我們將使用一個員工 API,該 API 包含兩個 HTTP 端點:獲取所有員工和創建員工:
- GET /employees
- POST /employees
為了客户端和服務器之間的通信,我們將使用一個簡單的 DTO(數據傳輸對象)來封裝基本員工數據:
public class Employee {
public long id;
public String title;
// standard constructor and setters/getters
}現在,我們準備編寫使用 RestTemplate 獲取和創建 Employee 對象列表的代碼。
3. 使用 RestTemplate 獲取對象列表
通常在調用 GET 請求時,可以使用 RestTemplate 的簡化方法,例如 getForObject()。
getForObject(URI url, Class<T> responseType)
此方法使用 GET 謂詞向指定的 URI 發送請求,並將響應主體轉換為請求的 Java 類型。 這對於大多數類效果很好,但它有一個限制:我們無法發送對象列表。
問題在於 Java 通用類型中的類型擦除。 在應用程序運行時,它無法知道列表中對象類型。 這意味着列表中的數據無法反序列化為適當的類型。
幸運的是,我們有兩項解決方案來解決這個問題。
3.1. 使用數組
首先,我們可以使用 <em >RestTemplate</em> 的 <em >getForEntity()</em>> 方法通過 <em >responseType</em> 參數獲取一個對象數組。 指定此處 <em >class</em> 時,它將與 <em >ResponseEntity</em> 的參數類型相匹配:
ResponseEntity<Employee[]> response =
restTemplate.getForEntity(
"http://localhost:8080/employees/",
Employee[].class);
Employee[] employees = response.getBody();我們也可以使用 RestTemplate.exchange 達到相同的效果。
需要注意的是,在這裏承擔主要工作的還是 ResponseExtractor,因此如果我們需要進一步的定製,可以調用 execute 並提供我們自己的實例。
3.2. 使用包裝類
某些API會返回一個頂層對象,其中包含員工列表,而不是直接返回列表。為了處理這種情況,我們可以使用一個包裝類,該包裝類包含員工列表。
public class EmployeeList {
private List<Employee> employees;
public EmployeeList() {
employees = new ArrayList<>();
}
// standard constructor and getter/setter
}現在我們可以使用更簡單的 getForObject() 方法來獲取員工列表:
EmployeeList response = restTemplate.getForObject(
"http://localhost:8080/employees",
EmployeeList.class);
List<Employee> employees = response.getEmployees();這段代碼更加簡潔,但需要一個額外的包裝對象。
4. 使用 RestTemplate 發佈對象列表
現在我們來看如何從客户端將對象列表發送到服務器。 就像上面一樣,RestTemplate 提供了簡化調用 POST 請求的方法:
postForObject(URI url, Object request, Class<T> responseType)
此方法將 HTTP POST 請求發送到指定的 URI,帶有可選的請求主體,並將響應轉換為指定類型。 與上面 GET 場景不同,我們無需擔心類型擦除。
這是因為我們現在是從 Java 對象到 JSON 進行轉換。 列表中的對象及其類型由 JVM 知道,因此它們將被正確序列化:
List<Employee> newEmployees = new ArrayList<>();
newEmployees.add(new Employee(3, "Intern"));
newEmployees.add(new Employee(4, "CEO"));
restTemplate.postForObject(
"http://localhost:8080/employees/",
newEmployees,
ResponseEntity.class);4.1. 使用包裝類
如果我們需要使用包裝類以保持與上述 GET 場景的一致性,這也很簡單。我們可以使用 RestTemplate 發送一個新的列表。
List<Employee> newEmployees = new ArrayList<>();
newEmployees.add(new Employee(3, "Intern"));
newEmployees.add(new Employee(4, "CEO"));
restTemplate.postForObject(
"http://localhost:8080/employees",
new EmployeeList(newEmployees),
ResponseEntity.class);5. 結論
使用 <em >RestTemplate</em> 是構建 HTTP 客户端,與我們的服務進行通信的一種簡單方法。
它提供了多種方法,用於處理所有 HTTP 方法和簡單對象。通過少量的額外代碼,我們可以輕鬆地使用它來處理對象列表。