呼叫 RESTful Web 服務

本指南將引導您完成建立應用程式以呼叫 RESTful Web 服務的過程。

您將建構什麼

您將建構一個應用程式,使用 Spring 的 RestTemplatehttps://127.0.0.1:8080/api/random 取得隨機的 Spring Boot 引言。

您需要什麼

如何完成本指南

如同大多數 Spring 入門指南,您可以從頭開始並完成每個步驟,或者您可以跳過您已熟悉的基本設定步驟。無論哪種方式,您最終都會得到可運作的程式碼。

若要從頭開始,請前往 從 Spring Initializr 開始

若要跳過基礎步驟,請執行以下操作

完成後,您可以將您的結果與 gs-consuming-rest/complete 中的程式碼進行比較。

從 Spring Initializr 開始

您可以使用這個 預先初始化的專案,然後按一下 Generate 以下載 ZIP 檔案。此專案已設定為符合本教學課程中的範例。

手動初始化專案

  1. 導覽至 https://start.spring.io。此服務會拉取應用程式所需的所有依賴項目,並為您完成大部分設定。

  2. 選擇 Gradle 或 Maven 以及您想要使用的語言。本指南假設您選擇 Java。

  3. 按一下 Dependencies 並選取 Spring Web

  4. 按一下 Generate

  5. 下載產生的 ZIP 檔案,這是根據您的選擇設定的 Web 應用程式的封存檔。

如果您的 IDE 具有 Spring Initializr 整合,您可以從您的 IDE 完成此程序。
您也可以從 Github 分叉專案,並在您的 IDE 或其他編輯器中開啟它。

取得 REST 資源

專案設定完成後,您可以建立一個簡單的應用程式來呼叫 RESTful 服務。

在您可以執行此操作之前,您需要 REST 資源的來源。我們在 https://github.com/spring-guides/quoters 提供了一個此類服務的範例。您可以在另一個終端機中執行該應用程式,並在 https://127.0.0.1:8080/api/random 存取結果。該位址會隨機擷取關於 Spring Boot 的引言,並以 JSON 文件形式傳回。其他有效的位址包括 https://127.0.0.1:8080/api/ (適用於所有引言) 和 https://127.0.0.1:8080/api/1 (適用於第一個引言)、https://127.0.0.1:8080/api/2 (適用於第二個引言) 等等 (目前最多 10 個)。

如果您透過 Web 瀏覽器或 curl 請求該 URL,您會收到類似以下的 JSON 文件

{
   type: "success",
   value: {
      id: 10,
      quote: "Really loving Spring Boot, makes stand alone Spring apps easy."
   }
}

這很容易,但在透過瀏覽器或 curl 擷取時並不是非常有用。

以程式設計方式呼叫 REST Web 服務是一種更有用的方法。為了協助您完成這項任務,Spring 提供了一個方便的範本類別,名為 RestTemplateRestTemplate 使與大多數 RESTful 服務的互動變得像一行咒語一樣簡單。它甚至可以將資料繫結到自訂網域類型。

首先,您需要建立一個網域類別來包含您需要的資料。以下清單顯示了 Quote 記錄類別,您可以將其用作您的網域類別

src/main/java/com/example/consumingrest/Quote.java

package com.example.consumingrest;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public record Quote(String type, Value value) { }

這個簡單的 Java 記錄類別使用 Jackson JSON 處理程式庫的 @JsonIgnoreProperties 註釋,以指示應忽略此類型中未繫結的任何屬性。

若要將您的資料直接繫結到您的自訂類型,您需要指定變數名稱與從 API 傳回的 JSON 文件中的金鑰完全相同。如果您的變數名稱和 JSON 文件中的金鑰不符,您可以使用 @JsonProperty 註釋來指定 JSON 文件的確切金鑰。(此範例將每個變數名稱與 JSON 金鑰比對,因此您在此處不需要該註釋。)

您還需要一個額外的類別,以嵌入內部的引言本身。Value 記錄類別滿足了這個需求,並顯示在以下清單中(位於 src/main/java/com/example/consumingrest/Value.java

package com.example.consumingrest;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public record Value(Long id, String quote) { }

這使用相同的註釋,但對應到其他資料欄位。

完成應用程式

Initializr 會建立一個具有 main() 方法的類別。以下清單顯示了 Initializr 建立的類別(位於 src/main/java/com/example/consumingrest/ConsumingRestApplication.java

package com.example.consumingrest;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ConsumingRestApplication {

	public static void main(String[] args) {
		SpringApplication.run(ConsumingRestApplication.class, args);
	}

}

現在您需要在 ConsumingRestApplication 類別中新增一些其他內容,使其顯示來自我們 RESTful 來源的引言。您需要新增

  • 記錄器,將輸出傳送到日誌(在此範例中為主控台)。

  • RestTemplate,它使用 Jackson JSON 處理程式庫來處理傳入的資料。

  • CommandLineRunner,它會在啟動時執行 RestTemplate(並因此擷取我們的引言)。

以下清單顯示了完成的 ConsumingRestApplication 類別(位於 src/main/java/com/example/consumingrest/ConsumingRestApplication.java

package com.example.consumingrest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Profile;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
public class ConsumingRestApplication {

	private static final Logger log = LoggerFactory.getLogger(ConsumingRestApplication.class);

	public static void main(String[] args) {
		SpringApplication.run(ConsumingRestApplication.class, args);
	}

	@Bean
	public RestTemplate restTemplate(RestTemplateBuilder builder) {
		return builder.build();
	}

	@Bean
	@Profile("!test")
	public CommandLineRunner run(RestTemplate restTemplate) throws Exception {
		return args -> {
			Quote quote = restTemplate.getForObject(
					"https://127.0.0.1:8080/api/random", Quote.class);
			log.info(quote.toString());
		};
	}
}

最後,您需要設定伺服器埠。quoters 應用程式使用預設伺服器埠 8080,因此此應用程式也不能使用相同的埠。您可以將伺服器埠設定為 8081,方法是將以下行新增至應用程式屬性(Initializr 為您建立的)

server.port=8081

執行應用程式

您可以使用 Gradle 或 Maven 從命令列執行應用程式。您也可以建置一個包含所有必要依賴項目、類別和資源的單一可執行 JAR 檔案並執行它。建置可執行 jar 可以輕鬆地在整個開發生命週期、跨不同環境等情況下,將服務作為應用程式運送、版本控制和部署。

如果您使用 Gradle,您可以使用 ./gradlew bootRun 執行應用程式。或者,您可以使用 ./gradlew build 建置 JAR 檔案,然後執行 JAR 檔案,如下所示

java -jar build/libs/gs-consuming-rest-0.1.0.jar

如果您使用 Maven,您可以使用 ./mvnw spring-boot:run 執行應用程式。或者,您可以使用 ./mvnw clean package 建置 JAR 檔案,然後執行 JAR 檔案,如下所示

java -jar target/gs-consuming-rest-0.1.0.jar
此處描述的步驟會建立可執行的 JAR。您也可以 建置傳統的 WAR 檔案

您應該會看到類似以下的輸出,但帶有隨機引言

2019-08-22 14:06:46.506  INFO 42940 --- [           main] c.e.c.ConsumingRestApplication           : Quote{type='success', value=Value{id=1, quote='Working with Spring Boot is like pair-programming with the Spring developers.'}}
如果您看到錯誤訊息,內容為 Could not extract response: no suitable HttpMessageConverter found for response type [class com.example.consumingrest.Quote],則可能是您處於無法連線到後端服務 (如果您可以連線到後端服務,則會傳送 JSON) 的環境中。也許您位於公司 Proxy 後方。嘗試將 http.proxyHosthttp.proxyPort 系統屬性設定為適合您環境的值。

摘要

恭喜!您剛剛使用 Spring Boot 開發了一個簡單的 REST 用戶端。

取得程式碼