iT邦幫忙

2025 iThome 鐵人賽

DAY 19
0
Software Development

spring boot 3 學習筆記系列 第 19

Day19 - Spring Boot Web 篇:建立你的第一個 API 端點

  • 分享至 

  • xImage
  •  

今日這個單元,我們將一起探索 Spring Boot 如何像一位聰明的總機,接收來自網路世界的請求,並給予回應。

學習目標

完成本單元後,你將能夠:

  1. 理解 Spring Boot 如何處理網頁請求 (Web Request)。
  2. 認識 @Controller, @RequestMapping, @ResponseBody, 和 @RestController 這些核心註解 (Annotation) 的作用。
  3. 親手寫出一個可以透過瀏覽器訪問並回傳 "Hello, World!" 的 API (應用程式介面, Application Programming Interface)。

第一站:@Controller - 應用程式的總機

在 Spring Boot 應用程式中,@Controller 是一切的起點,它是你與使用者互動的橋樑。

簡單來說,它告訴 Spring 框架:「嘿!這個類別 (Class) 是個控制器,專門負責處理來自網頁瀏覽器的請求 (Request),並決定要回應 (Response) 什麼結果。」

你可以把 @Controller 想像成一間公司的總機。當有電話(HTTP 請求)打進來時,總機會先接聽,然後判斷來電者的意圖,再決定要轉接到哪個分機去處理。

import org.springframework.stereotype.Controller;

@Controller // 標記這個類別是一個總機 (控制器)
public class MyFirstController {
    // ... 這裡將會定義各種分機 (處理方法)
}

第二站:@RequestMapping & @GetMapping - 指示轉接的分機號碼

光有總機還不夠,我們需要告訴總機,什麼樣的來電該轉接到哪個分機。這就是 @RequestMapping 的工作。它負責建立「請求的網址 (URL)」和「處理該請求的方法 (Method)」之間的一一對應關係。

  • @Controller:標記一個類別是總機
  • @RequestMapping:標記一個方法是分機,並指定這個分機專門處理哪個 URL 的來電。

在現代的 Spring Boot 開發中,為了讓程式碼更簡潔易讀,我們更常使用 @RequestMapping 的衍生註解 (Annotation),它們的語意更清晰:

  • @GetMapping:專門處理 GET 請求(通常用於獲取資料)。
  • @PostMapping:專門處理 POST 請求(通常用於新增資料)。
  • @PutMapping:專門處理 PUT 請求(通常用於更新資料)。
  • @DeleteMapping:專門處理 DELETE 請求(通常用於刪除資料)。

在今日入門單元,我們將聚焦在最常見的 @GetMapping

讓我們把總機和分機結合起來:

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller // 這是一個總機
public class MyFirstController {

    // 使用 @GetMapping 告訴總機:
    // 如果有人用 GET 方式訪問 "/hello" 這個路徑,
    // 就把請求轉交給下面的 sayHello() 方法處理。
    @GetMapping("/hello")
    public String sayHello() {
        // 這個方法回傳了一個字串 "welcome"
        return "welcome";
    }
}

當你啟動程式並在瀏覽器輸入 http://localhost:8080/hello,Spring Boot 會:

  1. 接收到對 /hello 路徑的 GET 請求。
  2. @Controller 標記的 MyFirstController 類別中,尋找與 /hello 路徑匹配的 @GetMapping
  3. 找到 sayHello() 方法並執行它。
  4. 得到回傳值 "welcome"

但這裡有一個關鍵問題:Spring 預設會把這個 "welcome" 當成一個視圖 (View) 的名稱,它會試圖去尋找一個叫做 welcome.html 的網頁檔案,然後把這個網頁的內容回傳給瀏覽器。

但如果我們不想回傳整個網頁,只想回傳 "Hello World" 這段文字資料呢?這就需要下一站的工具了。

第三站:@ResponseBody - 我回傳的是「資料」,不是「網頁」!

@ResponseBody 這個註解 (Annotation) 的核心任務非常明確,就是告訴 Spring 框架:

「請不要把我的回傳值當成視圖 (View) 名稱去尋找網頁檔案。請直接把這個回傳的內容,當作 HTTP 回應的主體 (Body) 送回去!」

這在開發 API 時至關重要,因為 API 的目的就是提供純粹的資料(最常見的是 JSON 格式),而不是完整的 HTML 頁面。

讓我們來改造一下剛剛的例子:

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class MyFirstController {

    @GetMapping("/hello-page")
    public String sayHelloPage() {
        // 沒有 @ResponseBody,Spring 會去找 welcome.html
        return "welcome";
    }

    @GetMapping("/hello-data")
    @ResponseBody // 加上這個註解!
    public String sayHelloData() {
        // 有了 @ResponseBody,Spring 會直接把 "Hello, World!" 這個字串回傳
        return "Hello, World!";
    }
}

現在:

  • 訪問 /hello-page,Spring 會去找 welcome.html
  • 訪問 /hello-data,瀏覽器會直接收到 Hello, World! 的純文字。

@ResponseBody 最強大的地方在於,它能自動將 Java 物件轉換成 JSON 格式。這得益於 Spring Boot 內建的 Jackson 函式庫 (Library)。

範例:回傳一個物件

// 假設你有一個 User 物件
public class User {
    private String name;
    private int age;
    // ... 省略建構子、getter 和 setter
}

@Controller
public class UserController {
    @GetMapping("/api/user")
    @ResponseBody // 告訴 Spring 直接回傳這個物件
    public User getUser() {
        User user = new User("John Doe", 30);
        // Spring 會自動將這個 user 物件序列化 (Serialize) 成 JSON
        return user;
    }
}

當你訪問 /api/user,你會在瀏覽器中看到標準的 JSON 格式資料:

{
  "name": "John Doe",
  "age": 30
}

第四站:@RestController - API 開發的標準配備

看到這裡,你可能會發現,在開發 API 時,我們幾乎總是需要同時使用 @Controller@ResponseBody

Spring 的設計者也想到了這一點,於是提供了一個更方便的複合註解 (Composite Annotation):@RestController

@RestController = @Controller + @ResponseBody

當你在一個類別上使用 @RestController,就等於告訴 Spring:「這個類別是一個專門用來提供 API、回傳資料的控制器,它裡面所有方法都預設啟用了 @ResponseBody 的功能!

這是現代 Spring Boot API 開發的標準作法

單元成果:打造最終版的 "Hello, World!" API

現在,讓我們用最精簡、最標準的方式來完成我們最初的目標。

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

// 使用 @RestController,兼具 @Controller 和 @ResponseBody 的功能
@RestController
public class HelloApiController {

    // 當使用者用 GET 方法訪問 "/api/hello" 路徑時,執行此方法
    @GetMapping("/api/hello")
    public String sayHello() {
        // 因為 @RestController 的關係,這個字串會直接被回傳
        return "Hello, World!";
    }
}

就是這麼簡單!

  1. @RestController: 宣告這是一個專門回傳資料的 API 控制器。
  2. @GetMapping("/api/hello"): 將 http://localhost:8080/api/hello 這個路徑的請求,交給 sayHello() 方法處理。
  3. return "Hello, World!": 方法回傳的字串,會直接成為瀏覽器收到的內容。

現在,啟動你的 Spring Boot 應用程式,打開瀏覽器訪問 http://localhost:8080/api/hello,你就能看到你的第一個 API 成功地回傳了 "Hello, World!"。

恭喜你,已經掌握了 Spring Boot 處理 Web 請求與回應的核心觀念!

相關資料來源


上一篇
Day18 - Spring Boot 依賴注入指南:深入理解 Bean - 作用域與生命週期
下一篇
Day20 - Spring Boot Web 篇:接收來自 URL 的動態參數
系列文
spring boot 3 學習筆記20
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言