這是我們對 REST 的概述的最後一部分。在前面的部分中,我們介紹了:
單擊“Next”按鈕。在下一個窗口中,指定“Maven Project”作為項目類型,指定“Group”和“Artifact”:
單擊“Next”按鈕。在下一個窗口中,我們需要選擇項目所需的 Spring Framework 組件。Spring Web 對我們來說已經足夠了:
單擊“下一步”按鈕。現在剩下的就是指示項目的名稱及其在文件系統中的位置:
單擊“完成”按鈕。項目創建完成,現在我們可以看到它的結構:
IDEA
單擊左上角的“新建”按鈕。接下來,選擇“Request”:
接下來,為其命名並保存。現在讓我們嘗試向服務器發送 POST 請求並創建第一個客戶:
我們以這種方式創建了多個客戶。然後我們將請求類型改為GET,向服務器發送請求:

創建項目
在本節中,我們將使用 Spring Boot 創建一個小型 RESTful 應用程序。我們的應用程序將對概述前一部分示例中的客戶實施 CRUD(創建、讀取、更新、刪除)操作。首先,我們將通過菜單創建一個新的 Spring Boot 應用程序:File -> New -> Project... 在打開的窗口中,選擇 Spring Initializr 並指定 Project SDK:




RestExampleApplication
為我們生成了一個Maven部署描述符(pom.xml)和應用程序的主類()。這是它們的樣子:
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.codegym.lessons/groupId>
<artifactId>rest_example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>rest_example</name>
<description>REST example project</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
休息示例應用程序:
@SpringBootApplication
public class RestExampleApplication {
public static void main(String[] args) {
SpringApplication.run(RestExampleApplication.class, args);
}
}
創建 REST 功能
我們的應用程序是一個客戶管理系統。因此,我們需要做的第一件事是創建一個客戶實體。它將是一個 POJO(普通舊 Java 對象)類。在包內創建一個model
包com.codegym.lessons.rest_example
。在包內model
,創建Customer
:
public class Customer {
private Integer id;
private String name;
private String email;
private String phone;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}
該服務將對客戶實施 CRUD 操作。下一步是創建將實現這些操作的服務。在com.codegym.lessons.rest_example
包中,創建一個service
包。在裡面,創建一個CustomerService
界面。下面是帶註釋的接口代碼:
public interface CustomerService {
/**
* Creates a new customer
* @param customer - Customer to be created
*/
void create(Customer customer);
/**
* Returns a list of all existing customers
* @return List of customers
*/
List<Customer> readAll();
/**
* Returns a customer based on its ID
* @param id - Customer ID
* @return - Customer object with the given ID
*/
Customer read(int id);
/**
* Updates the customer with the given ID,
* according to the passed customer
* @param customer - Customer to use to update the data
* @param id - ID of the customer you want to update
* @return - true if the data has been updated, otherwise false
*/
boolean update(Customer customer, int id);
/**
* Deletes the customer with the given ID
* @param id - ID of the customer to be deleted
* @return - true if the customer was deleted, otherwise false
*/
boolean delete(int id);
}
接下來,我們需要實現這個接口。現在一個Map<Integer, Customer>
將存儲我們的客戶。地圖的鍵是客戶 ID,值是客戶本身。這樣做是為了不讓這個例子因使用真實數據庫的細節而超載。但是,將來我們將能夠編寫該接口的另一個實現,這將使連接到真實數據庫成為可能。在service
包中,創建接口的實現CustomerService
:
@Service
public class CustomerServiceImpl implements CustomerService {
// Customer repository
private static final Map<Integer, Customer> CUSTOMER_REPOSITORY_MAP = new HashMap<>();
// Variable for generating a customer ID
private static final AtomicInteger CUSTOMER_ID_HOLDER = new AtomicInteger();
@Override
public void create(Customer customer) {
final int customerId = CUSTOMER_ID_HOLDER.incrementAndGet();
customer.setId(customerId);
CUSTOMER_REPOSITORY_MAP.put(customerId, customer);
}
@Override
public List<Customer> readAll() {
return new ArrayList<>(CUSTOMER_REPOSITORY_MAP.values());
}
@Override
public Customer read(int id) {
return CUSTOMER_REPOSITORY_MAP.get(id);
}
@Override
public boolean update(Customer customer, int id) {
if (CUSTOMER_REPOSITORY_MAP.containsKey(id)) {
customer.setId(id);
CUSTOMER_REPOSITORY_MAP.put(id, customer);
return true;
}
return false;
}
@Override
public boolean delete(int id) {
return CUSTOMER_REPOSITORY_MAP.remove(id) != null;
}
}
註解@Service
告訴 spring 這個類是一個服務。這是一種特殊類型的類,用於實現某些業務應用程序邏輯。隨後,由於這個註解,Spring 將使用依賴注入在所有需要它的地方為我們提供這個類的實例。現在是創建控制器的時候了。這是一個特殊的類,我們將在其中實現處理髮送到端點 (URI) 的客戶端請求的邏輯。為了使這一切更清楚,我們將逐步創建此類。首先,創建類本身並添加對以下內容的依賴CustomerService
:
@RestController
public class CustomerController {
private final CustomerService customerService;
@Autowired
public CustomerController(CustomerService customerService) {
this.customerService = customerService;
}
}
讓我們解釋一下註解: @RestController告訴 Spring 這個類是一個 REST 控制器。換句話說,這個類實現了處理客戶端請求的邏輯。 @Autowired告訴 Spring 需要在這裡添加一個依賴。我們將接口傳遞CustomerService
給構造函數。早些時候,我們用註釋標記了這個服務的實現@Service
,現在 Spring 將能夠將這個實現的實例傳遞給控制器的構造函數。接下來,我們將實現每個控制器方法來處理 CRUD 操作。讓我們從創建操作開始。為此,我們編寫了一個create
方法:
@PostMapping(value = "/customers")
public ResponseEntity<?> create(@RequestBody Customer customer) {
customerService.create(customer);
return new ResponseEntity<>(HttpStatus.CREATED);
}
我們來分析一下這個方法: @PostMapping(value = "/customers")
意思是這個方法處理髮送到地址“/customers”的POST請求。該方法返回一個ResponseEntity<?>
. AResponseEntity
是用於返迴響應的特殊類。稍後,我們將使用它向客戶端返回 HTTP 狀態代碼。該方法有一個@RequestBody Customer customer
參數。該參數的值來自請求體。註釋@RequestBody
表明了這一點。在方法體內,我們調用create()
之前創建的服務的方法,並將其傳遞給接收到的參數中的客戶控制器。ResponseEntity
然後我們通過創建一個新對象並將相應的HttpStatus
枚舉字段傳遞給它來返回“201 Created”狀態。接下來,我們將實現read
操作:首先,我們將實施操作以獲取所有可用客戶的列表:
@GetMapping(value = "/customers")
public ResponseEntity<List<Customer>> read() {
final List<Customer> customers = customerService.readAll();
return customers != null && !customers.isEmpty()
? new ResponseEntity<>(customers, HttpStatus.OK)
: new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
讓我們深入研究: @GetMapping(value = "/customers")
— 這裡的一切都與註解相似@PostMapping
,但現在我們正在處理 GET 請求。這次我們返回一個ResponseEntity<List<Customer>>
,除了 HTTP 狀態之外,我們還將返回一個響應主體,這將是客戶列表。在 Spring 的 REST 控制器中,一切都是 POJO 對象和 POJO 對象的集合,它們作為響應主體返回並自動序列化為 JSON,除非另有說明。這非常適合我們。在方法內部,我們使用我們的服務來獲取所有客戶的列表。接下來,如果列表不為 null 且不為空,則我們使用ResponseEntity
返回客戶列表和“200 OK”HTTP 狀態代碼的類。否則,我們簡單地返回“404 Not Found”HTTP 狀態代碼。現在我們將實現使用其 ID 獲取客戶的能力:
@GetMapping(value = "/customers/{id}")
public ResponseEntity<Customer> read(@PathVariable(name = "id") int id) {
final Customer customer = customerService.read(id);
return customer != null
? new ResponseEntity<>(customer, HttpStatus.OK)
: new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
這裡的一個新事物是路徑變量。該變量在 URI 中定義:value = "/customers/{id}"
。我們用花括號表示它。我們int
使用註釋將其作為方法參數接收@PathVariable(name = "id")
。此方法將接受以 形式發送到 URI 的請求/customers/{id}
,其中{id}
代表任何數值。該值隨後通過int id
變量傳遞給方法參數。在正文中,我們Customer
使用我們的服務和接收到的id
. 然後,通過類比列表,我們返回“200 OK”狀態和對象Customer
本身,或者如果系統沒有客戶,則返回“404 Not Found”狀態id
。我們還需要實現兩個操作:更新和刪除。以下是這些方法的代碼:
@PutMapping(value = "/customers/{id}")
public ResponseEntity<?> update(@PathVariable(name = "id") int id, @RequestBody Customer customer) {
final boolean updated = customerService.update(customer, id);
return updated
? new ResponseEntity<>(HttpStatus.OK)
: new ResponseEntity<>(HttpStatus.NOT_MODIFIED);
}
@DeleteMapping(value = "/customers/{id}")
public ResponseEntity<?> delete(@PathVariable(name = "id") int id) {
final boolean deleted = customerService.delete(id);
return deleted
? new ResponseEntity<>(HttpStatus.OK)
: new ResponseEntity<>(HttpStatus.NOT_MODIFIED);
}
這些方法本質上沒有什麼新東西,所以我們將跳過詳細描述。唯一值得一提的是update()
方法處理PUT請求(@PutMapping
註解),delete()
方法處理DELETE請求(DeleteMapping
註解)。這是控制器的完整代碼:
@RestController
public class CustomerController {
private final CustomerService customerService;
@Autowired
public CustomerController(CustomerService customerService) {
this.customerService = customerService;
}
@PostMapping(value = "/customers")
public ResponseEntity<?> create(@RequestBody Customer customer) {
customerService.create(customer);
return new ResponseEntity<>(HttpStatus.CREATED);
}
@GetMapping(value = "/customers")
public ResponseEntity<List<Customer>> read() {
final List<Customer> customers = customerService.readAll();
return customers != null && !customers.isEmpty()
? new ResponseEntity<>(customers, HttpStatus.OK)
: new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
@GetMapping(value = "/customers/{id}")
public ResponseEntity<Customer> read(@PathVariable(name = "id") int id) {
final Customer customer = customerService.read(id);
return customer != null
? new ResponseEntity<>(customer, HttpStatus.OK)
: new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
@PutMapping(value = "/customers/{id}")
public ResponseEntity<?> update(@PathVariable(name = "id") int id, @RequestBody Customer customer) {
final boolean updated = customerService.update(customer, id);
return updated
? new ResponseEntity<>(HttpStatus.OK)
: new ResponseEntity<>(HttpStatus.NOT_MODIFIED);
}
@DeleteMapping(value = "/customers/{id}")
public ResponseEntity<?> delete(@PathVariable(name = "id") int id) {
final boolean deleted = customerService.delete(id);
return deleted
? new ResponseEntity<>(HttpStatus.OK)
: new ResponseEntity<>(HttpStatus.NOT_MODIFIED);
}
}
因此,我們項目的結構如下: 
啟動和測試
要啟動我們的應用程序,只需運行類main()
中的方法即可RestExampleApplication
。但是要測試 RESTful Web 服務,我們需要下載額外的軟件。事實上,從普通瀏覽器發送 GET 請求非常簡單,但普通瀏覽器無法發送 POST、PUT 和 DELETE 請求。別擔心:您可以使用一個名為 Postman 的程序來發送任何 HTTP 請求。你可以在這裡下載。下載並安裝 Postman 後,我們開始測試我們的應用程序。為此,打開程序並創建一個新請求: 



概括
恭喜!我們已經充分介紹了 REST。有大量的材料,但希望它對你有用:-
我們了解了 REST 是什麼。
-
我們了解了 REST 是如何產生的。
-
我們談到了這種架構風格的局限性和背後的原則:
- 客戶端-服務器架構
- 無國籍的
- 緩存
- 統一接口
- 圖層
- 按需代碼(可選)
-
我們探索了 REST 提供的好處
-
我們詳細檢查了服務器和客戶端如何通過 HTTP 協議相互交互。
-
我們仔細研究了請求和響應。我們剖析了它們的組成部分。
-
最後,我們通過使用 Spring Boot 編寫自己的小型 RESTful 應用程序獲得了一些實踐經驗。我們甚至學會瞭如何使用 Postman 對其進行測試。
家庭作業
嘗試以下操作:- 按照上面的描述,創建您自己的 Spring Boot 項目並實現與課程中相同的邏輯。完全重複一切。
- 啟動應用程序。
- 下載並配置 Postman(或任何其他用於發送請求的工具,例如 curl)。
- 按照課程中描述的相同方式測試 POST 和 GET 請求。
- 自己測試 PUT 和 DELETE 請求。
GO TO FULL VERSION