package com.example.accessingdatarest;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
@Entity
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String firstName;
private String lastName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
使用 REST 訪問 JPA 資料
您將構建什麼
您將使用 Spring Data REST 構建一個 Spring 應用程式,該應用程式允許您建立和檢索儲存在資料庫中的 Person
物件。Spring Data REST 結合了 Spring HATEOAS 和 Spring Data JPA 的特性,並自動將它們整合在一起。
Spring Data REST 也支援 Spring Data Neo4j、Spring Data Gemfire 和 Spring Data MongoDB 作為後端資料儲存,但它們不屬於本指南的範圍。 |
您需要什麼
-
大約 15 分鐘
-
一個喜歡的文字編輯器或 IDE
-
Java 17 或更高版本
如何完成本指南
要在本地環境中檢視最終結果,您可以執行以下操作之一
-
下載並解壓本指南的原始碼倉庫
-
使用 Git 克隆倉庫:
git clone https://github.com/spring-guides/gs-accessing-data-rest.git
-
Fork 倉庫,這樣您可以透過提交 pull request 來請求修改本指南
從 Spring Initializr 開始
您可以使用這個預配置專案,然後點選 Generate 下載 ZIP 檔案。該專案已配置好,適合本教程中的示例。
手動初始化專案
-
導航到 https://start.spring.io。此服務會為您拉取應用程式所需的所有依賴項並完成大部分設定。
-
選擇 Gradle 或 Maven,以及您想使用的語言。本指南假設您選擇了 Java。
-
點選 Dependencies,然後選擇 Rest Repositories、Spring Data JPA 和 H2 Database。
-
點選 Generate。
-
下載生成的 ZIP 檔案,這是一個根據您的選擇配置好的 Web 應用程式壓縮包。
如果您的 IDE 集成了 Spring Initializr,您可以直接在 IDE 中完成此過程。 |
您也可以從 Github 上 fork 專案,然後在您的 IDE 或其他編輯器中開啟它。 |
建立領域物件
建立一個新的領域物件來表示一個人,如下面的列表(位於 src/main/java/com/example/accessingdatarest/Person.java
中)所示
Person
物件包含名字和姓氏。(還有一個 ID 物件被配置為自動生成,所以您無需處理它。)
建立 Person 倉庫
接下來,您需要建立一個簡單的倉庫,如下面的列表(位於 src/main/java/com/example/accessingdatarest/PersonRepository.java
中)所示
package com.example.accessingdatarest;
import java.util.List;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
@RepositoryRestResource(collectionResourceRel = "people", path = "people")
public interface PersonRepository extends PagingAndSortingRepository<Person, Long>, CrudRepository<Person,Long> {
List<Person> findByLastName(@Param("name") String name);
}
這個倉庫是一個介面,允許您執行涉及 Person
物件的各種操作。它透過繼承 Spring Data Commons 中定義的 PagingAndSortingRepository
介面來獲得這些操作。
在執行時,Spring Data REST 會自動建立此介面的實現。然後,它使用 @RepositoryRestResource 註解指示 Spring MVC 在 /people
處建立 RESTful 端點。
匯出倉庫不需要使用 @RepositoryRestResource 。它僅用於更改匯出細節,例如使用 /people 而不是預設值 /persons 。 |
這裡您還定義了一個自定義查詢,用於根據 lastName
檢索 Person
物件列表。您可以在本指南後面看到如何呼叫它。
Spring Boot 自動啟動 Spring Data JPA 來建立 PersonRepository
的具體實現,並將其配置為使用 JPA 與後端記憶體資料庫通訊。
Spring Data REST 構建在 Spring MVC 之上。它建立了一系列 Spring MVC 控制器、JSON 轉換器和其他 bean,以提供 RESTful 前端。這些元件連線到 Spring Data JPA 後端。當您使用 Spring Boot 時,所有這些都是自動配置的。如果您想了解它是如何工作的,可以檢視 Spring Data REST 中的 RepositoryRestMvcConfiguration
。
執行應用程式
您現在可以透過執行 AccessingDataRestApplication
中的 main 方法來執行應用程式。您可以在 IDE 中執行程式,或者在專案根目錄中執行以下 Gradle 命令
./gradlew bootRun
或者,您可以使用 Maven 執行以下命令來執行應用程式
./mvnw spring-boot:run
測試應用程式
現在應用程式正在執行,您可以對其進行測試。您可以使用任何您喜歡的 REST 客戶端。以下示例使用 *nix 工具 curl
。
首先您想檢視頂層服務。以下示例展示瞭如何執行此操作
$ curl https://:8080 { "_links" : { "people" : { "href" : "https://:8080/people{?page,size,sort}", "templated" : true } } }
前面的示例初步展示了該伺服器提供的內容。在 https://:8080/people
處有一個 people
連結。它有一些選項,例如 ?page
、?size
和 ?sort
。
Spring Data REST 對 JSON 輸出使用 HAL 格式。它非常靈活,並提供了一種方便的方式來在提供的資料旁邊提供連結。 |
以下示例展示瞭如何檢視人員記錄(目前沒有)
$ curl https://:8080/people { "_embedded" : { "people" : [] }, "_links" : { "self" : { "href" : "https://:8080/people{?page,size,sort}", "templated" : true }, "search" : { "href" : "https://:8080/people/search" } }, "page" : { "size" : 20, "totalElements" : 0, "totalPages" : 0, "number" : 0 } }
目前沒有元素,因此也沒有頁面。是時候建立一個新的 Person
了!以下列表展示瞭如何執行此操作
$ curl -i -H "Content-Type:application/json" -d '{"firstName": "Frodo", "lastName": "Baggins"}' https://:8080/people HTTP/1.1 201 Created Server: Apache-Coyote/1.1 Location: https://:8080/people/1 Content-Length: 0 Date: Wed, 26 Feb 2014 20:26:55 GMT
-
-i
:確保您可以看到包含頭部資訊的響應訊息。顯示了新建立的Person
的 URI。 -
-H "Content-Type:application/json"
:設定內容型別,以便應用程式知道負載包含一個 JSON 物件。 -
-d '{"firstName": "Frodo", "lastName": "Baggins"}'
:是要傳送的資料。 -
如果您使用 Windows,上面的命令將在 WSL 上工作。如果您無法安裝 WSL,您可能需要將單引號替換為雙引號並轉義現有的雙引號,例如
-d "{\"firstName\": \"Frodo\", \"lastName\": \"Baggins\"}"
。
請注意 POST 操作的響應如何包含 Location 頭部。這包含了新建立資源的 URI。Spring Data REST 還有兩種方法(RepositoryRestConfiguration.setReturnBodyOnCreate(…) 和 setReturnBodyOnUpdate(…) )可用於配置框架立即返回剛建立的資源的表示形式。RepositoryRestConfiguration.setReturnBodyForPutAndPost(…) 是一個快捷方法,用於為建立和更新操作啟用表示響應。 |
您可以查詢所有人員,如下例所示
$ curl https://:8080/people { "_links" : { "self" : { "href" : "https://:8080/people{?page,size,sort}", "templated" : true }, "search" : { "href" : "https://:8080/people/search" } }, "_embedded" : { "people" : [ { "firstName" : "Frodo", "lastName" : "Baggins", "_links" : { "self" : { "href" : "https://:8080/people/1" } } } ] }, "page" : { "size" : 20, "totalElements" : 1, "totalPages" : 1, "number" : 0 } }
people
物件包含一個列表,其中包括 Frodo
。請注意它如何包含一個 self
連結。Spring Data REST 還使用 Evo Inflector 將實體名稱複數化以進行分組。
您可以直接查詢單個記錄,如下所示
$ curl https://:8080/people/1 { "firstName" : "Frodo", "lastName" : "Baggins", "_links" : { "self" : { "href" : "https://:8080/people/1" } } }
這可能看起來完全是基於 Web 的。然而,在幕後,有一個 H2 關係型資料庫。在生產環境中,您可能會使用一個真正的資料庫,例如 PostgreSQL。 |
在本指南中,只有一個領域物件。在一個更復雜的系統中,如果領域物件相互關聯,Spring Data REST 會呈現額外的連結,以幫助導航到相關記錄。 |
您可以找到所有自定義查詢,如下例所示
$ curl https://:8080/people/search { "_links" : { "findByLastName" : { "href" : "https://:8080/people/search/findByLastName{?name}", "templated" : true } } }
您可以看到查詢的 URL,包括 HTTP 查詢引數 name
。請注意,這與介面中嵌入的 @Param("name")
註解匹配。
以下示例展示瞭如何使用 findByLastName
查詢
$ curl https://:8080/people/search/findByLastName?name=Baggins { "_embedded" : { "persons" : [ { "firstName" : "Frodo", "lastName" : "Baggins", "_links" : { "self" : { "href" : "https://:8080/people/1" } } } ] } }
由於您在程式碼中將其定義為返回 List<Person>
,它將返回所有結果。如果您將其定義為僅返回 Person
,它將選擇其中一個 Person
物件返回。由於這可能不可預測,您可能不想對可以返回多個條目的查詢這樣做。
您還可以發出 PUT
、PATCH
和 DELETE
REST 呼叫來分別替換、更新或刪除現有記錄。以下示例使用 PUT
呼叫
$ curl -X PUT -H "Content-Type:application/json" -d '{"firstName": "Bilbo", "lastName": "Baggins"}' https://:8080/people/1 $ curl https://:8080/people/1 { "firstName" : "Bilbo", "lastName" : "Baggins", "_links" : { "self" : { "href" : "https://:8080/people/1" } } }
以下示例使用 PATCH
呼叫
$ curl -X PATCH -H "Content-Type:application/json" -d '{"firstName": "Bilbo Jr."}' https://:8080/people/1 $ curl https://:8080/people/1 { "firstName" : "Bilbo Jr.", "lastName" : "Baggins", "_links" : { "self" : { "href" : "https://:8080/people/1" } } }
PUT 替換整個記錄。未提供的欄位將被替換為 null 。您可以使用 PATCH 更新部分專案。 |
您還可以刪除記錄,如下例所示
$ curl -X DELETE https://:8080/people/1 $ curl https://:8080/people { "_links" : { "self" : { "href" : "https://:8080/people{?page,size,sort}", "templated" : true }, "search" : { "href" : "https://:8080/people/search" } }, "page" : { "size" : 20, "totalElements" : 0, "totalPages" : 0, "number" : 0 } }
這種超媒體驅動介面的一個便捷之處在於,您可以使用 curl(或您喜歡的任何 REST 客戶端)來發現所有 RESTful 端點。您無需與客戶交換正式的合同或介面文件。
總結
恭喜!您已成功開發了一個具有 基於超媒體的 RESTful 前端和基於 JPA 的後端的應用程式。
另請參閱
以下指南也可能對您有所幫助
想編寫新指南或為現有指南做貢獻?請檢視我們的貢獻指南。
所有指南的程式碼均以 ASLv2 許可證釋出,而內容則以 署名-禁止演繹(Attribution, NoDerivatives)知識共享許可協議 釋出。 |