1. 程式人生 > >Spring Boot2 系列教程(三十一)Spring Boot 構建 RESTful 風格應用

Spring Boot2 系列教程(三十一)Spring Boot 構建 RESTful 風格應用

RESTful ,到現在相信已經沒人不知道這個東西了吧!關於 RESTful 的概念,我這裡就不做過多介紹了,傳統的 Struts 對 RESTful 支援不夠友好 ,但是 SpringMVC 對於 RESTful 提供了很好的支援,常見的相關注解有:

@RestController
@GetMapping
@PutMapping
@PostMapping
@DeleteMapping
@ResponseBody
...

這些註解都是和 RESTful 相關的,在移動網際網路中,RESTful 得到了非常廣泛的使用。RESTful 這個概念提出來很早,但是以前沒有移動網際網路時,我們做的大部分應用都是前後端不分的,在這種架構的應用中,資料基本上都是在後端渲染好返回給前端展示的,此時 RESTful 在 Web 應用中基本就沒用武之地,移動網際網路的興起,讓我們一套後臺對應多個前端專案,因此前後端分離,RESTful 順利走上前臺。

Spring Boot 繼承自 Spring + SpringMVC, SpringMVC 中對於 RESTful 支援的特性在 Spring Boot 中全盤接收,同時,結合 Jpa 和 自動化配置,對於 RESTful 還提供了更多的支援,使得開發者幾乎不需要寫程式碼(很少幾行),就能快速實現一個 RESTful 風格的增刪改查。

接下來,鬆哥通過一個簡單的案例,來向大家展示 Spring Boot 對於 RESTful 的支援。

實戰

建立工程

首先建立一個 Spring Boot 工程,引入 WebJpaMySQLRest Repositories 依賴:

建立完成後,還需要鎖定 MySQL 驅動的版本以及加入 Druid 資料庫連線池,完整依賴如下:

<dependencies>
    <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>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>1.1.10</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
        <version>5.1.27</version>
    </dependency>
</dependencies>

配置資料庫

主要配置兩個,一個是資料庫,另一個是 Jpa:

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.url=jdbc:mysql:///test01
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.database-platform=mysql
spring.jpa.database=mysql

這裡的配置,和 Jpa 中的基本一致。

前面五行配置了資料庫的基本資訊,包括資料庫連線池、資料庫使用者名稱、資料庫密碼、資料庫連線地址以及資料庫驅動名稱。

接下來的五行配置了 JPA 的基本資訊,分別表示生成 SQL 的方言、打印出生成的 SQL 、每次啟動專案時根據實際情況選擇是否更新表、資料庫平臺是 MySQL。

這兩段配置是關於 MySQL + JPA 的配置,沒用過 JPA 的小夥伴可以參考鬆哥之前的 JPA 文章:http://www.javaboy.org/2019/0407/springboot-jpa.html

構建實體類

@Entity(name = "t_book")
public class Book {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(name = "book_name")
    private String name;
    private String author;
    //省略 getter/setter
}
public interface BookRepository extends JpaRepository<Book,Long> {
}

這裡一個是配置了一個實體類 Book,另一個則是配置了一個 BookRepository ,專案啟動成功後,框架會根據 Book 類的定義,在資料庫中自動建立相應的表,BookRepository 介面則是繼承自 JpaRepository ,JpaRepository 中自帶了一些基本的增刪改查方法。

好了,程式碼寫完了。

啥?你好像啥都沒寫啊?是的,啥都沒寫,啥都不用寫,一個 RESTful 風格的增刪改查應用就有了,這就是 Spring Boot 的魅力!

測試

此時,我們就可以啟動專案進行測試了,使用 POSTMAN 來測試(大家也可以自行選擇趁手的 HTTP 請求工具)。

此時我們的專案已經預設具備了一些介面,我們分別來看:

根據 id 查詢介面
  • http://127.0.0.1:8080/books/{id}

這個介面表示根據 id 查詢某一本書:

分頁查詢
  • http://127.0.0.1:8080/books

這是一個批量查詢介面,預設請求路徑是類名首字母小寫,並且再加一個 s 字尾。這個介面實際上是一個分頁查詢介面,沒有傳引數,表示查詢第一頁,每頁 20 條資料。

查詢結果中,除了該有的資料之外,也包含了分頁資料:

分頁資料中:

  1. size 表示每頁查詢記錄數
  2. totalElements 表示總記錄數
  3. totalPages 表示總頁數
  4. number 表示當前頁數,從0開始計

如果要分頁或者排序查詢,可以使用 _links 中的連結。http://127.0.0.1:8080/books?page=1&size=3&sort=id,desc

新增

也可以新增資料,新增是 POST 請求,資料通過 JSON 的形式傳遞,如下:

新增成功之後,預設會返回新增成功的資料。

修改

修改介面預設也是存在的,資料修改請求是一個 PUT 請求,修改的引數也是通過 JSON 的形式傳遞:

預設情況下,修改成功後,會返回修改成功的資料。

刪除

當然也可以通過 DELETE 請求根據 id 刪除資料:

刪除成功後,是沒有返回值的。

不需要幾行程式碼,一個基本的增刪改查就有了。

這些都是預設的配置,這些預設的配置實際上都是在 JpaRepository 的基礎上實現的,實際專案中,我們還可以對這些功能進行定製。

查詢定製

最廣泛的定製,就是查詢,因為增刪改操作的變化不像查詢這麼豐富。對於查詢的定製,非常容易,只需要提供相關的方法即可。例如根據作者查詢書籍:

public interface BookRepository extends JpaRepository<Book,Long> {
    List<Book> findBookByAuthorContaining(@Param("author") String author);
}

注意,方法的定義,引數要有 @Param 註解。

定製完成後,重啟專案,此時就多了一個查詢介面,開發者可以通過 http://localhost:8080/books/search 來檢視和 book 相關的自定義介面都有哪些:

查詢結果表示,只有一個自定義介面,介面名就是方法名,而且查詢結果還給出了介面呼叫的示例。我們來嘗試呼叫一下自己定義的查詢介面:

開發者可以根據實際情況,在 BookRepository 中定義任意多個查詢方法,查詢方法的定義規則和 Jpa 中一模一樣(不懂 Jpa 的小夥伴,可以參考乾貨|一文讀懂 Spring Data Jpa!,或者在鬆哥個人網站 www.javaboy.org 上搜索 JPA,有相關教程參考)。但是,這樣有一個缺陷,就是 Jpa 中方法名太長,因此,如果不想使用方法名作為介面名,則可以自定義介面名:

public interface BookRepository extends JpaRepository<Book, Long> {
    @RestResource(rel = "byauthor",path = "byauthor")
    List<Book> findBookByAuthorContaining(@Param("author") String author);
}

@RestResource 註解中,兩個引數的含義:

  • rel 表示介面查詢中,這個方法的 key
  • path 表示請求路徑

這樣定義完成後,表示介面名為 byauthor ,重啟專案,繼續查詢介面:

除了 relpath 兩個屬性之外,@RestResource 中還有一個屬性,exported 表示是否暴露介面,預設為 true ,表示暴露介面,即方法可以在前端呼叫,如果僅僅只是想定義一個方法,不需要在前端呼叫這個方法,可以設定 exported 屬性為 false

如果不想暴露官方定義好的方法,例如根據 id 刪除資料,只需要在自定義介面中重寫該方法,然後在該方法上加 @RestResource 註解並且配置相關屬性即可。

public interface BookRepository extends JpaRepository<Book, Long> {
    @RestResource(rel = "byauthor",path = "byauthor")
    List<Book> findBookByAuthorContaining(@Param("author") String author);
    @Override
    @RestResource(exported = false)
    void deleteById(Long aLong);
}

另外生成的 JSON 字串中的集合名和單個 item 的名字都是可以自定義的:

@RepositoryRestResource(collectionResourceRel = "bs",itemResourceRel = "b",path = "bs")
public interface BookRepository extends JpaRepository<Book, Long> {
    @RestResource(rel = "byauthor",path = "byauthor")
    List<Book> findBookByAuthorContaining(@Param("author") String author);
    @Override
    @RestResource(exported = false)
    void deleteById(Long aLong);
}

path 屬性表示請求路徑,請求路徑預設是類名首字母小寫+s,可以在這裡自己重新定義。

其他配置

最後,也可以在 application.properties 中配置 REST 基本引數:

spring.data.rest.base-path=/api
spring.data.rest.sort-param-name=sort
spring.data.rest.page-param-name=page
spring.data.rest.limit-param-name=size
spring.data.rest.max-page-size=20
spring.data.rest.default-page-size=0
spring.data.rest.return-body-on-update=true
spring.data.rest.return-body-on-create=true

配置含義,從上往下,依次是:

  1. 給所有的介面新增統一的字首
  2. 配置排序引數的 key ,預設是 sort
  3. 配置分頁查詢時頁碼的 key,預設是 page
  4. 配置分頁查詢時每頁查詢頁數的 key,預設是size
  5. 配置每頁最大查詢記錄數,預設是 20 條
  6. 分頁查詢時預設的頁碼
  7. 更新成功時是否返回更新記錄
  8. 新增成功時是否返回新增記錄

總結

本文主要向大家介紹了 Spring Boot 中快速實現一個 RESTful 風格的增刪改查應用的方案,整體來說還是比較簡單的,並不難。相關案例我已上傳到 GitHub 上了,小夥伴可以自行下載:https://github.com/lenve/javaboy-code-samples。

關於本文,有問題歡迎留言討論。

掃碼關注鬆哥,公眾號後臺回覆 2TB,獲取鬆哥獨家 超2TB 免費 Java 學習乾貨

相關推薦

Spring Boot2 系列教程()Spring Boot 構建 RESTful 風格應用

RESTful ,到現在相信已經沒人不知道這個東西了吧!關於 RESTful 的概念,我這裡就不做過多介紹了,傳統的 Struts 對 RESTful 支援不夠友好 ,但是 SpringMVC 對於 RESTful 提供了很好的支援,常見的相關注解有: @RestController @GetMapping

Spring Boot2 系列教程(二)整合 MyBatis

前面兩篇文章和讀者聊了 Spring Boot 中最簡單的資料持久化方案 JdbcTemplate,JdbcTemplate 雖然簡單,但是用的並不多,因為它沒有 MyBatis 方便,在 Spring+SpringMVC 中整合 MyBatis 步驟還是有點複雜的,要配置多個 Bean,Spring Boo

Spring Boot2 系列教程()Spring Boot 整合 Ehcache

用慣了 Redis ,很多人已經忘記了還有另一個快取方案 Ehcache ,是的,在 Redis 一統江湖的時代,Ehcache 漸漸有點沒落了,不過,我們還是有必要了解下 Ehcache ,在有的場景下,我們還是會用到 Ehcache。 今天鬆哥就來和大家聊聊 Spring Boot 中使用 Ehcach

Spring Boot2 系列教程(二四)Spring Boot 整合 Jpa

Spring Boot 中的資料持久化方案前面給大夥介紹了兩種了,一個是 JdbcTemplate,還有一個 MyBatis,JdbcTemplate 配置簡單,使用也簡單,但是功能也非常有限,MyBatis 則比較靈活,功能也很強大,據我所知,公司採用 MyBatis 做資料持久化的相當多,但是 MyBat

Spring Boot2 系列教程(二五)Spring Boot 整合 Jpa 多資料來源

本文是 Spring Boot 整合資料持久化方案的最後一篇,主要和大夥來聊聊 Spring Boot 整合 Jpa 多資料來源問題。在 Spring Boot 整合JbdcTemplate 多資料來源、Spring Boot 整合 MyBatis 多資料來源以及 Spring Boot 整合 Jpa 多資料

Spring Boot2 系列教程(二六)Spring Boot 整合 Redis

在 Redis 出現之前,我們的快取框架各種各樣,有了 Redis ,快取方案基本上都統一了,關於 Redis,鬆哥之前有一個系列教程,尚不瞭解 Redis 的小夥伴可以參考這個教程: Redis 教程合集 使用 Java 操作 Redis 的方案很多,Jedis 是目前較為流行的一種方案,除了 Jedi

Spring Boot2 系列教程(二八)Spring Boot 整合 Session 共享

這篇文章是鬆哥的原創,但是在第一次釋出的時候,忘了標記原創,結果被好多號轉發,導致我後來整理的時候自己沒法標記原創了。寫了幾百篇原創技術乾貨了,有一兩篇忘記標記原創進而造成的一點點小小損失也能接受,不過還是要和小夥伴們說明一下。 在傳統的單服務架構中,一般來說,只有一個伺服器,那麼不存在 Session

Spring Boot2 系列教程(二九)Spring Boot 整合 Redis

經過 Spring Boot 的整合封裝與自動化配置,在 Spring Boot 中整合Redis 已經變得非常容易了,開發者只需要引入 Spring Data Redis 依賴,然後簡單配下 redis 的基本資訊,系統就會提供一個 RedisTemplate 供開發者使用,但是今天鬆哥想和大夥聊的不是這種

Spring Boot2 系列教程()理解 Spring Boot 專案中的 parent

前面和大夥聊了 Spring Boot 專案的三種建立方式,這三種建立方式,無論是哪一種,建立成功後,pom.xml 座標檔案中都有如下一段引用: <parent> <groupId>org.springframework.boot</groupId> &l

Spring Boot2 系列教程(六)自定義 Spring Boot 中的 starter

我們使用 Spring Boot,基本上都是沉醉在它 Stater 的方便之中。Starter 為我們帶來了眾多的自動化配置,有了這些自動化配置,我們可以不費吹灰之力就能搭建一個生產級開發環境,有的小夥伴會覺得這個 Starter 好神奇呀!其實 Starter 也都是 Spring + SpringMVC

Spring Boot2 系列教程(二十三)理解 Spring Data Jpa

有很多讀者留言希望鬆哥能好好聊聊 Spring Data Jpa! 其實這個話題鬆哥以前零零散散的介紹過,在我的書裡也有介紹過,但是在公眾號中還沒和大夥聊過,因此本文就和大家來仔細聊聊 Spring Data 和 Jpa! 本文大綱: 1. 故事的主角 1.1 Jpa 1.1.1 JPA 是什麼 Jav

Spring cloud系列教程篇- Spring cloud整合Eureka總結篇

Spring cloud系列教程第十篇- Spring cloud整合Eureka總結篇 本文主要內容: 1:spring cloud整合Eureka總結 本文是由凱哥(凱哥Java:kagejava)釋出的《spring cloud系列》教程的總第十篇: 本文是幾個維度中的第一個維度:註冊與發現維度配置中心

Spring Boot2 系列教程()Spring Boot 中的靜態資源配置

當我們使用 SpringMVC 框架時,靜態資源會被攔截,需要新增額外配置,之前老有小夥伴在微信上問鬆哥 Spring Boot 中的靜態資源載入問題:“鬆哥,我的 HTML 頁面好像沒有樣式?”,今天我就通過一篇文章,來和大夥仔細聊一聊這個問題。 1. SSM 中的配置 要講 Spring Boot 中的問

Spring Boot2 系列教程(二)@ControllerAdvice 的種使用場景

嚴格來說,本文並不算是 Spring Boot 中的知識點,但是很多學過 SpringMVC 的小夥伴,對於 @ControllerAdvice 卻並不熟悉,Spring Boot 和 SpringMVC 一脈相承,@ControllerAdvice 在 Spring Boot 中也有廣泛的使用場景,因此本文

Spring Boot入門教程(): 自定義Starter

在springboot中,使用的最多的就是starter。starter可以理解為一個可拔插式的外掛,例如,你想使用jdbc外掛,那麼可以使用spring-boot-starter-jdbc;如果想使用mongodb,可以使用spring-boot-starte

Spring Boot2 系列教程()純 Java 搭建 SSM 專案

在 Spring Boot 專案中,正常來說是不存在 XML 配置,這是因為 Spring Boot 不推薦使用 XML ,注意,並非不支援,Spring Boot 推薦開發者使用 Java 配置來搭建框架,Spring Boot 中,大量的自動化配置都是通過 Java 配置來實現的,這一套實現方案,我們也可

Spring Boot2 系列教程(二)建立 Spring Boot 專案的種方式

我最早是 2016 年底開始寫 Spring Boot 相關的部落格,當時使用的版本還是 1.4.x ,文章發表在 CSDN 上,閱讀量最大的一篇有 43W+,如下圖: 2017 年由於種種原因,就沒有再繼續更新 Spring Boot 相關的部落格了,2018年又去寫書了,也沒更新,現在 Spring

Spring Boot2 系列教程()Spring Boot 整合 Freemarker

今天來聊聊 Spring Boot 整合 Freemarker。 Freemarker 簡介 這是一個相當老牌的開源的免費的模版引擎。通過 Freemarker 模版,我們可以將資料渲染成 HTML 網頁、電子郵件、配置檔案以及原始碼等。Freemarker 不是面向終端使用者的,而是一個 Java 類庫,我

Spring Boot2 系列教程(四)CORS 解決跨域問題

今天和小夥伴們來聊一聊通過CORS解決跨域問題。 同源策略 很多人對跨域有一種誤解,以為這是前端的事,和後端沒關係,其實不是這樣的,說到跨域,就不得不說說瀏覽器的同源策略。 同源策略是由 Netscape 提出的一個著名的安全策略,它是瀏覽器最核心也最基本的安全功能,現在所有支援 JavaScript 的瀏覽

Spring Boot2 系列教程(五)定義系統啟動任務的兩種方式

在 Servlet/Jsp 專案中,如果涉及到系統任務,例如在專案啟動階段要做一些資料初始化操作,這些操作有一個共同的特點,只在專案啟動時進行,以後都不再執行,這裡,容易想到web基礎中的三大元件( Servlet、Filter、Listener )之一 Listener ,這種情況下,一般定義一個 Serv