1 前言

Springboot + Spring MVC 大大簡化了 Web 應用的 RESTful 開發,而 Spring Data REST 更簡單。 Spring Data REST 是建立在 Data Repository 之上的,它能直接把 resositoryHATEOAS 風格暴露成 Web 服務,而不需要再手寫 Controller 層。

HATEOAS ,即 Hypermedia as the Engine of Application State ,它是一種更成熟的 REST 模型,在資源的表達中包含了鏈接信息,客戶端可以根據鏈接來發現可執行的動作。

Spring Data REST 支持 Spring Data JPASpring Data MongoDBSpring Data Neo4jSpring Data GenFireSpring Data Cassandra ,這裏選擇大家比較熟悉的 JPA

2 舉個例子

我們用例子來感受一下吧。

2.1 創建項目

我們通過 Spring Initializr 來快速創建 Springboot 項目。選中的依賴組件如下:

  • (1) Spring Web :提供 Web 服務;
  • (2) Rest Repositories :提供 Spring Data REST 的支持;
  • (3) Spring Data JPA :通過 JPA 提供 Repository 方式的數據訪問;
  • (4) H2 DatabaseH2 數據庫,爲了方便簡潔,使用該數據庫。

導入後對應的 pom.xml 中依賴如下:

<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>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
  <groupId>com.h2database</groupId>
  <artifactId>h2</artifactId>
  <scope>runtime</scope>
</dependency>

2.2 實體類

創建一個實體類 User ,如下所示:

package com.pkslow.rest.entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;
    private String name;
    private Integer age;
    private String email;
  
  //getter & setter
}

2.3 Repository接口定義

定義 Repository 接口用於操作數據庫,如下所示:

package com.pkslow.rest.repo;

import com.pkslow.rest.entity.User;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;

@RepositoryRestResource(path = "user")
public interface UserRepository extends CrudRepository<User, Integer> {
}

註解 RepositoryRestResourceData REST 用於暴露 Repositorypath 爲訪問路徑,設置爲 user ,則訪問地址爲 http://localhost:8080/user

2.4 啓動訪問

準備好以上代碼,直接啓動 Springboot 應用即可,我們把端口設置爲 8080 ,訪問如下:

我們用 Postman 做一個基本操作。

新增:

查詢:

通過主鍵 ID 查詢:

修改:

刪除:

不難發現,返回的 Json 都帶有鏈接,這就是 HATEOAS 風格。

3 更多探索

3.1 分頁及排序功能

可以快速實現分頁及排序功能,只需要把 Repository 的父接口改爲 PagingAndSortingRepository 即可,如下所示:

@RepositoryRestResource(path = "user")
public interface UserRepository extends PagingAndSortingRepository<User, Integer> {
}

其實就是多了兩個方法 findAll(Sort var1)findAll(Pageable var1) ,如下所示:

public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {
    Iterable<T> findAll(Sort var1);

    Page<T> findAll(Pageable var1);
}

查詢 http://localhost:8080/user?page=1&size=2&sort=id,desc ,表示查詢第二頁,每頁2條記錄,以 ID 倒序展示。如下:

{
  "_embedded": {
    "users": [
      {
        "name": "pkslow.com",
        "age": 18,
        "email": "[email protected]",
        "_links": {
          "self": {
            "href": "http://localhost:8080/user/33"
          },
          "user": {
            "href": "http://localhost:8080/user/33"
          }
        }
      },
      {
        "name": "pkslow.com",
        "age": 18,
        "email": "[email protected]",
        "_links": {
          "self": {
            "href": "http://localhost:8080/user/32"
          },
          "user": {
            "href": "http://localhost:8080/user/32"
          }
        }
      }
    ]
  },
  "_links": {
    "first": {
      "href": "http://localhost:8080/user?page=0&size=2&sort=id,desc"
    },
    "prev": {
      "href": "http://localhost:8080/user?page=0&size=2&sort=id,desc"
    },
    "self": {
      "href": "http://localhost:8080/user?page=1&size=2&sort=id,desc"
    },
    "next": {
      "href": "http://localhost:8080/user?page=2&size=2&sort=id,desc"
    },
    "last": {
      "href": "http://localhost:8080/user?page=17&size=2&sort=id,desc"
    },
    "profile": {
      "href": "http://localhost:8080/profile/user"
    }
  },
  "page": {
    "size": 2,
    "totalElements": 35,
    "totalPages": 18,
    "number": 1
  }
}

可以發現 page 是從 0 開始的, 1 表示第二頁;返回結果還提供了第一頁、上一頁、本頁、下一頁、最後一頁的鏈接;以及分頁信息。

3.2 事件監聽

REST 提供了8個基於 Repository 的事件,如下:

BeforeCreateEvent
AfterCreateEvent
BeforeSaveEvent
AfterSaveEvent
BeforeLinkSaveEvent
AfterLinkSaveEvent
BeforeDeleteEvent
AfterDeleteEvent

添加一個自定義事件如下:

package com.pkslow.rest.event;

import com.pkslow.rest.entity.User;
import org.springframework.data.rest.core.event.AbstractRepositoryEventListener;
import org.springframework.stereotype.Component;

@Component
public class PkslowEventListener extends AbstractRepositoryEventListener<User> {

    @Override
    public void onBeforeCreate(User entity) {
        System.out.println("pkslow creating:" + entity);
    }

    @Override
    public void onBeforeSave(User entity) {
        System.out.println("pkslow saving:" + entity);
    }

    @Override
    public void onAfterDelete(User entity) {
        System.out.println("pkslow deleted:" + entity);
    }
}

分別執行了增加、修改、刪除後,日誌如下:

pkslow creating:User{id=null, name='pkslow.com', age=18, email='[email protected]'}
pkslow saving:User{id=32, name='pkslow.com', age=20, email='[email protected]'}
pkslow deleted:User{id=14, name='pkslow.com', age=18, email='[email protected]'}

說明事件成功執行,結合這個功能,可以實現很多業務邏輯,如刪除後記錄操作日誌,並刪除其它相關數據。

3.3 路徑

默認基礎路徑是 / ,可以通過 spring.data.rest.base-path=api 進行配置,這樣就變成了 localhost:8080/api/user

4 總結

本文介紹了 Spring Data REST ,可以方便大家進行 RESTful 服務開發。但據瞭解,項目中使用的並不多,簡單學習一下,不失是一種瞭解 Spring 全家桶及架構理念的方式。

參考文檔:

官方文檔

歡迎關注微信公衆號< 南瓜慢說 >,將持續爲你更新...

相關文章