{"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 開始
您可以使用這個預初始化專案,然後點選“生成”下載一個 ZIP 檔案。該專案已配置為符合本教程中的示例。
手動初始化專案
-
導航到 https://start.spring.io。此服務會為您拉取應用程式所需的所有依賴項,併為您完成大部分設定。
-
選擇 Gradle 或 Maven 以及您想要使用的語言。
-
在“Artifact”表單欄位中輸入“rest-service”。
-
點選 Dependencies 並選擇 Spring Web。
-
單擊生成。
-
下載生成的 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 記錄類或 Kotlin 資料類,如以下列表所示
package com.example.restservice;
public record Greeting(long id, String content) { }
package com.example.restservice
data class Greeting(val id: Long, val content: String)
此應用程式使用 Jackson JSON 庫自動將 Greeting 型別的例項編組為 JSON。Jackson 預設包含在 Web 啟動器中。 |
建立資源控制器
在 Spring 構建 RESTful Web 服務的方法中,HTTP 請求由控制器處理。這些元件由 @RestController 註解標識,以下列表中所示的 GreetingController 類透過返回 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(defaultValue = "World") String name) {
return new Greeting(counter.incrementAndGet(), template.formatted(name));
}
}
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
private const val template = "Hello, %s!"
@RestController
class GreetingController {
private val counter = AtomicLong()
@GetMapping("/greeting")
fun greeting(@RequestParam name: String = "World") =
Greeting(counter.incrementAndGet(), template.format(name))
}
這個控制器簡潔而簡單,但其背後有很多事情發生。我們一步一步地進行分解。
@GetMapping 註解確保將對 /greeting 的 HTTP GET 請求對映到 greeting() 方法。
還有其他 HTTP 動詞的配套註解(例如,用於 POST 的 @PostMapping)。還有一個 @RequestMapping 註解,它們都派生自該註解,並且可以作為同義詞(例如,@RequestMapping(method=GET))。 |
@RequestParam 將查詢字串引數 name 的值繫結到 greeting() 方法的 name 引數中。如果請求中缺少 name 引數,則使用 World 的 defaultValue。
方法體的實現根據 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 位於類路徑上,Spring 的 JacksonJsonHttpMessageConverter 會自動選擇用於將 Greeting 例項轉換為 JSON。
執行服務
Spring Initializr 會為您建立一個應用程式類。在這種情況下,您無需進一步修改該類。以下列表顯示了 RestServiceApplication 應用程式類
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);
}
}
package com.example.restservice
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
@SpringBootApplication
class RestServiceApplication
fun main(args: Array<String>) {
runApplication<RestServiceApplication>(*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 服務。