{"id":1,"content":"Hello, World!"}
構建 RESTful Web 服務
本指南將引導你完成使用 Spring 建立一個“Hello, World”RESTful Web 服務的整個過程。
你將構建什麼
你將構建一個服務,該服務將接受對 https://:8080/greeting
的 HTTP GET 請求。
它將響應一個問候語的 JSON 表示,如下所示:
你可以使用查詢字串中的可選 name
引數來自定義問候語,如下所示:
https://:8080/greeting?name=User
name
引數的值將覆蓋預設值 World
並反映在響應中,如下所示:
{"id":1,"content":"Hello, User!"}
你需要什麼
-
大約 15 分鐘
-
一個喜歡的文字編輯器或 IDE
-
Java 17 或更高版本
-
你也可以將程式碼直接匯入到你的 IDE 中
如何完成本指南
像大多數 Spring 入門指南一樣,你可以從頭開始完成每個步驟,或者跳過你已經熟悉的基本設定步驟。無論哪種方式,你都會得到可以執行的程式碼。
要從頭開始,請繼續閱讀從 Spring Initializr 開始。
要跳過基礎,請執行以下操作:
-
下載並解壓本指南的原始碼倉庫,或者使用 Git 克隆:
git clone https://github.com/spring-guides/gs-rest-service.git
-
進入
gs-rest-service/initial
目錄 -
跳到建立資源表示類。
完成時,你可以將你的結果與 gs-rest-service/complete
中的程式碼進行對照。
從 Spring Initializr 開始
你可以使用這個預配置專案,然後點選 Generate 下載 ZIP 檔案。這個專案已經配置好以適應本教程中的示例。
手動初始化專案
-
訪問 https://start.spring.io。此服務會引入應用程式所需的所有依賴項,併為你完成大部分設定。
-
選擇 Gradle 或 Maven 以及你想使用的語言。本指南假設你選擇了 Java。
-
點選 Dependencies 並選擇 Spring Web。
-
點選 Generate。
-
下載生成的 ZIP 檔案,這是一個根據你的選擇配置好的 Web 應用程式的壓縮包。
如果你的 IDE 集成了 Spring Initializr,你可以在 IDE 中完成這個過程。 |
你也可以從 Github fork 該專案,並在你的 IDE 或其他編輯器中開啟。 |
建立資源表示類
現在你已經設定好專案和構建系統,可以建立你的 Web 服務了。
從思考服務互動開始。
該服務將處理對 /greeting
的 GET
請求,可選地包含查詢字串中的 name
引數。GET
請求應返回一個 200 OK
響應,其正文包含代表問候語的 JSON。它應該類似於以下輸出:
{
"id": 1,
"content": "Hello, World!"
}
id
欄位是問候語的唯一識別符號,而 content
是問候語的文字表示。
為了建模問候語表示,建立一個資源表示類。為此,提供一個用於 id
和 content
資料的 Java record 類,如下面的列表(來自 src/main/java/com/example/restservice/Greeting.java
)所示:
package com.example.restservice;
public record Greeting(long id, String content) { }
此應用程式使用 Jackson JSON 庫自動將 Greeting 型別的例項編組(marshal)為 JSON。Jackson 預設包含在 Web Starter 中。 |
建立資源控制器
在 Spring 構建 RESTful Web 服務的方法中,HTTP 請求由控制器處理。這些元件透過 @RestController
註解標識,如下面列表所示的 GreetingController
(來自 src/main/java/com/example/restservice/GreetingController.java
)透過返回 Greeting
類的新例項來處理對 /greeting
的 GET
請求:
package com.example.restservice;
import java.util.concurrent.atomic.AtomicLong;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class GreetingController {
private static final String template = "Hello, %s!";
private final AtomicLong counter = new AtomicLong();
@GetMapping("/greeting")
public Greeting greeting(@RequestParam(value = "name", defaultValue = "World") String name) {
return new Greeting(counter.incrementAndGet(), String.format(template, name));
}
}
這個控制器簡潔明瞭,但在底層做了很多工作。我們一步步來分析。
@GetMapping
註解確保 HTTP GET 請求到 /greeting
會對映到 greeting()
方法。
對於其他 HTTP 動詞(例如 POST 的 @PostMapping )也有相應的註解。此外,還有一個 @RequestMapping 註解,所有這些註解都派生自它,並且可以作為同義詞使用(例如 @RequestMapping(method=GET) )。 |
@RequestParam
將查詢字串引數 name
的值繫結到 greeting()
方法的 name
引數。如果請求中缺少 name
引數,則使用預設值 World
。
方法體的實現基於 counter
的下一個值建立並返回一個新的 Greeting
物件,該物件具有 id
和 content
屬性,並使用問候語 template
格式化給定的 name
。
傳統 MVC 控制器與前面所示的 RESTful Web 服務控制器之間的一個關鍵區別在於 HTTP 響應體的建立方式。RESTful Web 服務控制器不是依靠檢視技術在伺服器端將問候語資料渲染成 HTML,而是填充並返回一個 Greeting
物件。物件資料將直接作為 JSON 寫入 HTTP 響應。
此程式碼使用了 Spring 的 @RestController
註解,它將類標記為控制器,其中每個方法都返回一個領域物件而不是檢視。它是包含 @Controller
和 @ResponseBody
的簡寫。
Greeting
物件必須轉換為 JSON。得益於 Spring 的 HTTP 訊息轉換器支援,你無需手動執行此轉換。由於 Jackson 2 存在於類路徑中,Spring 的 MappingJackson2HttpMessageConverter
會自動選擇來將 Greeting
例項轉換為 JSON。
執行服務
Spring Initializr 會為你建立一個應用程式類。在這種情況下,你無需進一步修改該類。以下列表(來自 src/main/java/com/example/restservice/RestServiceApplication.java)顯示了該應用程式類:
package com.example.restservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class RestServiceApplication {
public static void main(String[] args) {
SpringApplication.run(RestServiceApplication.class, args);
}
}
@SpringBootApplication
是一個便捷註解,它包含了以下所有功能:
-
@Configuration
:將類標記為應用程式上下文的 Bean 定義來源。 -
@EnableAutoConfiguration
:告訴 Spring Boot 根據類路徑設定、其他 Bean 和各種屬性設定開始新增 Bean。例如,如果類路徑中有spring-webmvc
,則此註解會將應用程式標記為 Web 應用程式並激活關鍵行為,例如設定DispatcherServlet
。 -
@ComponentScan
:告訴 Spring 在com/example
包中查詢其他元件、配置和服務,從而找到控制器。
main()
方法使用 Spring Boot 的 SpringApplication.run()
方法啟動應用程式。你注意到沒有一行 XML 程式碼嗎?也沒有 web.xml
檔案。這個 Web 應用程式是 100% 純 Java 的,你無需處理任何底層或基礎設施的配置。
構建可執行 JAR
你可以使用 Gradle 或 Maven 從命令列執行應用程式。你還可以構建一個包含所有必要依賴項、類和資源的獨立可執行 JAR 檔案並執行它。構建可執行 JAR 可以輕鬆地在整個開發生命週期、跨不同環境等場景中將服務作為應用程式進行交付、版本控制和部署。
如果你使用 Gradle,可以使用 ./gradlew bootRun
執行應用程式。或者,你可以使用 ./gradlew build
構建 JAR 檔案,然後如下執行 JAR 檔案:
如果你使用 Maven,可以使用 ./mvnw spring-boot:run
執行應用程式。或者,你可以使用 ./mvnw clean package
構建 JAR 檔案,然後如下執行 JAR 檔案:
此處描述的步驟會建立一個可執行的 JAR。你也可以構建一個經典的 WAR 檔案。 |
將顯示日誌輸出。服務應在幾秒鐘內啟動並執行。
測試服務
服務啟動後,訪問 https://:8080/greeting
,你應該會看到:
{"id":1,"content":"Hello, World!"}
透過訪問 https://:8080/greeting?name=User
提供一個 name
查詢字串引數。注意 content
屬性的值如何從 Hello, World!
變為 Hello, User!
,如下面列表所示:
{"id":2,"content":"Hello, User!"}
此更改表明 GreetingController
中的 @RequestParam
配置按預期工作。name
引數已指定預設值 World
,但可以透過查詢字串顯式覆蓋。
同時注意 id
屬性如何從 1
變為 2
。這證明你在多個請求中使用的是同一個 GreetingController
例項,並且它的 counter
欄位在每次呼叫時都按預期遞增。
總結
恭喜!你剛剛使用 Spring 開發了一個 RESTful Web 服務。