知識庫 / Spring / Spring Boot RSS 訂閱

REST API 中 HTTP PUT 與 POST 的區別

REST,Spring Boot
HongKong
5
03:44 AM · Dec 06 ,2025

1. 概述

在本教程中,我們將研究兩個重要的 HTTP 方法,PUT 和 POST,這些方法在 REST 架構中被我們頻繁使用。 開發者在設計 RESTful Web 服務時,有時會為選擇這兩種方法而苦惱,這一點無需贅述。 因此,我們將通過在 Spring Boot 中實現一個簡單的 RESTful 應用來解決這個問題。

2. PUT 與 POST 的困境

在典型的 REST 架構中,客户端通過 HTTP 方法向服務器發送請求,用於創建、檢索、修改或刪除資源。雖然我們可以使用 PUT 和 POST 兩種方法來創建資源,但它們在用途上存在顯著差異。

根據 RFC 2616 標準,POST 方法應用於請求服務器將包含的實體作為現有資源的子級接受。這意味着 POST 方法調用將創建一個子資源,位於資源集合下。

相反,PUT 方法應用於請求服務器將包含的實體存儲在提供的 Request-URI 下。如果 Request-URI 指向服務器上已存在的資源,則提供的實體將被視為現有資源的修改版本。因此,PUT 方法調用將要麼創建一個新的資源,要麼更新一個現有資源

另一個重要的區別是,PUT 是一種冪等方法,而 POST 不是。例如,多次調用 PUT 方法將要麼創建一個新的資源,要麼更新同一個資源。與之相反,多次 POST 請求將導致相同的資源被創建多次。

3. 示例應用程序

為了演示 PUT 和 POST 方法之間的區別,我們將使用 Spring Boot 創建一個簡單的 RESTful Web 應用程序。該應用程序將存儲人們的姓名和地址。

3.1. Maven 依賴

首先,我們需要在我們的 pom.xml文件中添加 Spring Web、Spring Data JPA 和內存數據庫 H2 的依賴:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
</dependency>

3.2. 領域實體與存儲接口

首先,我們創建領域對象。對於通訊錄,我們將定義一個名為 AddressEntity 類,用於存儲個人的地址信息。為了簡化起見,我們的 Address 實體將包含 name(姓名)、city(城市)和 postalCode(郵政編碼)這三個字段:

@Entity
public class Address {

    private @Id @GeneratedValue Long id;
    private String name;
    private String city;
    private String postalCode;

    // constructors, getters, and setters
}

下一步是訪問數據庫中的數據。為了簡化操作,我們將利用 Spring Data JPA 的 JpaRepository,這允許我們在不編寫任何額外代碼的情況下執行 CRUD 功能:

public interface AddressRepository extends JpaRepository<Address, Long> {
}

3.3. REST 控制器

最後,我們需要為我們的應用程序定義 API 端點。我們將創建一個 RestController,它將從客户端消耗 HTTP 請求並返回適當的響應。

在這裏,我們將 定義一個 @PostMapping 用於創建新的地址並將其存儲在數據庫中,以及一個 @PutMapping 用於根據請求 URI 更新地址簿的內容。如果未找到 URI,則將創建一個新地址並將其存儲在數據庫中:

@RestController
public class AddressController {

    private final AddressRepository repository;

    AddressController(AddressRepository repository) {
        this.repository = repository;
    }

    @PostMapping("/addresses")
    Address createNewAddress(@RequestBody Address newAddress) {
        return repository.save(newAddress);
    }

    @PutMapping("/addresses/{id}")
    Address replaceEmployee(@RequestBody Address newAddress, @PathVariable Long id) {

        return repository.findById(id)
            .map(address -> {
                address.setCity(newAddress.getCity());
                address.setPin(newAddress.getPostalCode());
                return repository.save(address);
            })
            .orElseGet(() -> {
                return repository.save(newAddress);
            });
    }
    //additional methods omitted
}

3.4. cURL 請求

現在我們可以使用 cURL 向我們的服務器發送示例 HTTP 請求來測試我們開發的應用程序。

對於創建新地址,我們將數據包含在 JSON 格式中,並通過 POST 請求發送:

curl -X POST --header 'Content-Type: application/json' \
    -d '{ "name": "John Doe", "city": "Berlin", "postalCode": "10585" }' \ 
    http://localhost:8080/addresses

現在讓我們更新我們創建的地址的內容。我們將使用 URL 中的 id 發送一個 PUT 請求。在本例中,我們將更新我們剛剛創建的地址的 citypostalCode 部分。我們假設它已保存為 id = 1:

curl -X PUT --header 'Content-Type: application/json' \
  -d '{ "name": "John Doe", "city": "Frankfurt", "postalCode": "60306" }' \ 
  http://localhost:8080/addresses/1

4. 結論

在本文中,我們探討了 HTTP 方法 PUT 和 POST 的概念差異。此外,我們還學習瞭如何使用 Spring Boot 框架為開發 RESTful 應用程序實現這些方法。

綜上所述,我們應該使用 POST 方法來創建新的資源,使用 PUT 方法來更新現有資源。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.