本篇要點
- Spring Data REST的基本介紹。
- SpringBoot快速構建restful風格接口。
Spring Data REST概述
REST Web服務已經成為Web上應用程序集成的第一大手段。 REST的核心是定義一個包含與客戶端進行交互資源的系統。 這些資源以超媒體驅動的方式實現。
Spring MVC和Spring WebFlux各自提供了構建REST服務的堅實基礎。 但是,即使為multi-domain
對象系統實現最簡單的REST Web服務原則也可能很繁瑣,並且會導致大量樣板代碼。
Spring Data REST旨在解決這個問題,它建立在Spring Data存儲庫之上,並自動將其導出為REST資源,客戶端可以輕松查詢並調用存儲庫本身暴露出來的接口。
SpringBoot快速構建restful風格接口
SpringBoot構建Spring Data REST
是相當方便的,因為自動化配置的存在,spring-boot-starter-data-rest
可以讓你不需要寫多少代碼,就能輕松構建一套完整的rest應用。
除此之外,你需要引入數據存儲的依賴,它支持SpringData JPA、Spring Data MongoDB等,這里就使用JPA啦。正好我們前幾篇介紹過JPA的簡單使用:SpringBoot整合Spring Data JPA
創建項目,導入依賴
<!--jpa-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!--restful-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<!--web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
yml配置
server:
port: 8081
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/restful?serverTimezone=GMT%2B8
username: root
password: 123456
hikari:
maximum-pool-size: 20
minimum-idle: 5
jpa:
database: mysql
#在建表的時候,將默認的存儲引擎切換為 InnoDB
database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
# 配置在日志中打印出執行的 SQL 語句信息。
show-sql: true
# 配置指明在程序啟動的時候要刪除並且創建實體類對應的表。
hibernate:
ddl-auto: update
定義實體類
@Entity(name = "t_user")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
@Column(length = 20)
private Integer age;
}
定義Repository接口
public interface UserDao extends JpaRepository<User, Long> {
}
到這里為止,其實可以發現,和JPA文章沒啥差異,除了多引入了一個rest依賴。ok,啟動項目,先把表生成了再說。
啟動項目,我們就會發現JPA已經為我們將表結構創建完成,並且,一個基於Restful風格的增刪改查應用也已誕生,我們可以使用接口測試工具,進行測試。
測試Restful接口
默認的請求路徑是 類名首字母小寫+后綴s,這里就是users。
測試添加功能
POST: http://localhost:8081/users
{
"username": "summerday",
"password": "123456",
"age": 18
}
添加成功之后,返回信息如下:
{
"username": "summerday",
"password": "123456",
"age": 18,
"_links": {
"self": {
"href": "http://localhost:8081/users/1"
},
"user": {
"href": "http://localhost:8081/users/1"
}
}
}
測試刪除功能
DELETE : http://localhost:8081/users/1
// 刪除成功之后返回刪除的 id = 1
測試修改功能
PUT : http://localhost:8081/users/2
{
"username": "summerday111",
"password": "123456111",
"age": 181
}
同樣的,修改成功,將對應id為2的信息改為傳入信息,並返回更新后的信息。
{
"username": "summerday111",
"password": "123456111",
"age": 181,
"_links": {
"self": {
"href": "http://localhost:8081/users/2"
},
"user": {
"href": "http://localhost:8081/users/2"
}
}
}
測試根據id查詢
GET : http://localhost:8081/users/3
測試分頁查詢
GET : http://localhost:8081/users
分頁查詢結果:
{
"_embedded": {
"users": [
{
"username": "summerday111",
"password": "123456111",
"age": 181,
"_links": {
"self": {
"href": "http://localhost:8081/users/2"
},
"user": {
"href": "http://localhost:8081/users/2"
}
}
},
{
"username": "summerday",
"password": "123456",
"age": 18,
"_links": {
"self": {
"href": "http://localhost:8081/users/3"
},
"user": {
"href": "http://localhost:8081/users/3"
}
}
}
]
},
"_links": {
"self": {
"href": "http://localhost:8081/users"
},
"profile": {
"href": "http://localhost:8081/profile/users"
}
},
"page": {
"size": 20,
"totalElements": 2,
"totalPages": 1,
"number": 0
}
}
測試分頁+排序
GET : http://localhost:8081/users?page=0&size=1&sort=age,desc
第一頁,每頁size為1的記錄,按age逆序。
{
"_embedded": {
"users": [
{
"username": "summerday111",
"password": "123456111",
"age": 181,
"_links": {
"self": {
"href": "http://localhost:8081/users/2"
},
"user": {
"href": "http://localhost:8081/users/2"
}
}
}
]
},
"_links": {
"first": {
"href": "http://localhost:8081/users?page=0&size=1&sort=age,desc"
},
"self": {
"href": "http://localhost:8081/users?page=0&size=1&sort=age,desc"
},
"next": {
"href": "http://localhost:8081/users?page=1&size=1&sort=age,desc"
},
"last": {
"href": "http://localhost:8081/users?page=1&size=1&sort=age,desc"
},
"profile": {
"href": "http://localhost:8081/profile/users"
}
},
"page": {
"size": 1,
"totalElements": 2,
"totalPages": 2,
"number": 0
}
}
定制查詢
自定義查詢接口
public interface UserDao extends JpaRepository<User, Long> {
List<User> findUsersByUsernameContaining(@Param("username")String username);
}
訪問:http://localhost:8081/users/search
,查詢自定義接口。
{
"_links": {
"findUsersByUsernameContaining": {
"href": "http://localhost:8081/users/search/findUsersByUsernameContaining{?username}",
"templated": true
},
"self": {
"href": "http://localhost:8081/users/search"
}
}
}
測試一下這個方法:
GET : http://localhost:8081/users/search/findUsersByUsernameContaining?username=111
{
"_embedded": {
"users": [
{
"username": "summerday111",
"password": "123456111",
"age": 181,
"_links": {
"self": {
"href": "http://localhost:8081/users/2"
},
"user": {
"href": "http://localhost:8081/users/2"
}
}
}
]
},
"_links": {
"self": {
"href": "http://localhost:8081/users/search/findUsersByUsernameContaining?username=111"
}
}
}
自定義接口名
public interface UserDao extends JpaRepository<User, Long> {
//rel 表示接口查詢中,這個方法的 key
//path 表示請求路徑
@RestResource(rel = "auth", path = "auth")
User findByUsernameAndPassword(@Param("name") String username, @Param("pswd") String password);
}
繼續查詢自定義的接口:
"auth": {
"href": "http://localhost:8081/users/search/auth{?name,pswd}",
"templated": true
}
測試一下:
GET : http://localhost:8081/users/search/auth?name=summerday&pswd=123456
設置接口對前端隱藏
@Override
@RestResource(exported = false)
void deleteById(Long aLong);
定義生成JSON字符串的相關信息
@RepositoryRestResource(collectionResourceRel = "userList",itemResourceRel = "u",path = "user")
public interface UserDao extends JpaRepository<User, Long> {
}
此時路徑名為/user
:
GET : http://localhost:8081/user/2
{
"username": "summerday111",
"password": "123456111",
"age": 181,
"_links": {
"self": {
"href": "http://localhost:8081/user/2"
},
"u": {
"href": "http://localhost:8081/user/2"
}
}
}
其他配置屬性
Spring Data REST其他可配置的屬性,通過spring.data.rest.basePath=/v1
的形式指定。
屬性 | 描述 |
---|---|
basePath |
the root URI |
defaultPageSize |
每頁默認size |
maxPageSize |
|
pageParamName |
配置分頁查詢時頁碼的 key,默認是 page |
limitParamName |
配置分頁查詢時每頁查詢頁數的 key,默認是size |
sortParamName |
配置排序參數的 key ,默認是 sort |
defaultMediaType |
配置默認的媒體類型 |
returnBodyOnCreate |
添加成功時是否返回添加記錄 |
returnBodyOnUpdate |
更新成功時是否返回更新記錄 |