1. 概述
在本教程中,我们将快速浏览 REST 架构中经常使用的两个重要的 HTTP 方法 - PUT 和 POST。众所周知, 开发人员在设计 RESTful Web 服务时有时会难以在这两种方法之间进行选择 。因此,我们将通过在 Spring Boot 中简单实现 RESTful 应用程序来解决这个问题。
2. PUT 与 POST 困境
在典型的 REST 架构中,客户端以 HTTP 方法的形式向服务器发送请求,以创建、检索、修改或销毁资源。虽然 PUT 和 POST 都可用于创建资源,但它们之间的预期应用程序存在显着差异。
根据RFC 2616标准,应使用 POST 方法来请求服务器接受所包含的实体作为由 Request-URI 标识的现有资源的下属。这意味着 POST 方法调用将在资源集合下创建子资源 。
另一方面,PUT 方法应该用于请求服务器将所包含的实体存储在所提供的 Request-URI 下。如果请求 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.领域实体和存储库接口
让我们首先创建域对象。对于地址簿,我们定义一个名为 Address 的 实体 类,我们将用它来存储个人的地址信息。为了简单起见,我们将为我们的 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.休息控制器
最后,我们需要为应用程序定义 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 向我们的服务器发送示例 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 请求。在此示例中,我们将更新刚刚创建的地址的 城市 和 邮政编码 部分 - 我们假设它是使用 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 方法来更新现有资源。与往常一样,本教程的代码可在 GitHub 上获取。