中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何在Spring中利用REST實現一個分頁功能

發布時間:2021-01-16 10:26:51 來源:億速云 閱讀:423 作者:Leah 欄目:編程語言

本篇文章給大家分享的是有關如何在Spring中利用REST實現一個分頁功能,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

1.資源與表示

在我們開始設計分頁API之前,我們需要清楚地了解頁面作為資源或資源的表示。我們需要記住許多基本要素

一個頁面Page不是REST中的一個資源,而是其請求的屬性。

以資源名稱Product為構建分頁的例子,在高層次上我們確實有以下三個選項來構建分頁。

  • 將產品Product作為資源并使用查詢字符串來處理分頁以及其他參數,例如排序等(例如http://domainname/products?page=1)。

  • 第二個選項是將頁面Page用作資源和查詢字符串進行排序。(例如http://domainname/products/page/1?sort_by=date)。

  • 使用頁面Page作為資源和URL部分進行排序。(例如http://domainname/products/date/page/1)

考慮到上述問題,讓我們嘗試回答一些在設計REST API分頁時有用的問題。

  • 您是否將頁面Page視為頁面中產品的資源?

請記住,REST API不是圍繞任何預定義的規則或規范構建的,所有上述三個選項都是有效的,并且基于上述問題的答案。如果我們將頁面視為資源,則選項3是有效選擇;但如果我們說頁面上的產品是資源,那么選項3不再有效(在第1,2頁上的產品可能會在將來更改),就個人而言,我會選擇選項1,因為對我來說,頁面 Page 不是  資源Resouce,它是請求的屬性。

2.可發現性

可發現性  有助于使  RESTful API  更加實用和優雅。使REST API  可被發現經常被忽視。以下是REST API可發現性的高級摘要 。

  • 有了這個功能,REST API在對客戶端的響應中提供完整的URI意味著沒有客戶端需要“組合”URI。

  • 客戶端API獨立于URI結構。

  • 通過以上2點,API更加靈活,允許開發人員在不破壞API的情況下更改URI架構。(請記住,API提供所有URI,它們不是由客戶端API動態創建的)。

可發現性與REST API中的HATEOAS密切相關。REST API分頁可發現將通過"next","previous","first"和"last"鏈路作為響應數據的一部分。我們正在考慮如何在分頁期間將此功能添加到您的API。

3.分頁設計考慮因素

在構建REST API分頁界面時,讓我們快速介紹一些要點。

3.1 限制limit

限制允許API和客戶端控制結果集中請求的結果數。通過傳遞  limit 參數,您可以指定每個頁面要返回的項目數.API可以配置默認限制,但應允許客戶端指定限制。

http://hostname/products?page=1&limit=50

在上面的請求中,客戶端將限制設置為50.小心,同時允許客戶將limit 參數設置 , 設置為極高數量的限制會降低API性能。建議在API設計期間具有最大允許限制。

3.2 排序

排序總是與搜索和分頁并排。在設計REST API時,提供靈活性,讓客戶指定排序選項,同時從API返回結果。建議在設計API時使用  sort_by = [attribute  name] - [asc / desc]模式.API設計器應將允許的屬性名稱指定為sort參數。例如,您可以使用?name-asc按產品名稱排序或?name-desc反向排序。

4. Maven依賴

我們在Spring中處理REST分頁時介紹了所有基本內容。我們在這篇文章中使用了以下技術堆棧,但它可以在任何其他技術上實現,前提是您在設計時遵循所有基本原則。

  • Spring Boot

  • JPA.

  • Spring Data REST

在本文中使用Spring Data REST的原因之一是Data REST API支持的開箱即用功能。

我們將在pom.xml中添加以下依賴項

  1. Spring Boot JPA

  2. Spring Boot Data REST

  3. HATEOS和Web

<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-hateoas</artifactId>
  </dependency>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
   <groupId>org.hsqldb</groupId>
   <artifactId>hsqldb</artifactId>
   <scope>runtime</scope>
  </dependency>
</dependencies>

4.1 REST控制器:

@RestController
public class ProductRESTController {

 @Autowired
 private ProductService productService;

 @Autowired private EntityLinks links;

 @GetMapping(value = "/products", produces = MediaType.APPLICATION_JSON_VALUE)
 public ResponseEntity < PagedResources < ProductEntity >> AllProducts(Pageable pageable, PagedResourcesAssembler assembler) {
 Page < ProductEntity > products = productService.findAllProducts(pageable);
 PagedResources < ProductEntity > pr = assembler.toResource(products, linkTo(ProductRESTController.class).slash("/products").withSelfRel());
 HttpHeaders responseHeaders = new HttpHeaders();
 responseHeaders.add("Link", createLinkHeader(pr));
 return new ResponseEntity < > (assembler.toResource(products, linkTo(ProductRESTController.class).slash("/products").withSelfRel()), responseHeaders, HttpStatus.OK);
 }

 private String createLinkHeader(PagedResources < ProductEntity > pr) {
 final StringBuilder linkHeader = new StringBuilder();
 linkHeader.append(buildLinkHeader(pr.getLinks("first").get(0).getHref(), "first"));
 linkHeader.append(", ");
 linkHeader.append(buildLinkHeader(pr.getLinks("next").get(0).getHref(), "next"));
 return linkHeader.toString();
 }

 public static String buildLinkHeader(final String uri, final String rel) {
 return "<" + uri + ">; rel=\"" + rel + "\"";
 }
}

讓我們快速介紹上面代碼中的幾個要點。

  1. 我們使用  Pageable作為控制器的參數之一。這將有助于返回頁面而不是列表。

  2. Pageable具有所有必需的分頁信息。

  3. Pageable在Spring JPA中運行得非常好,并且透明地處理分頁。

4.2 Previous 和Next 鏈接

每個頁面響應將返回鏈接到當前頁面前面和后面的頁,這是基于使用IANA定義鏈接關系 prev 和  next。但是,如果您當前位于結果的第一頁,則不會呈現任何 prev鏈接。

我們來看下面的例子:

curl http://localhost:8080/products

{
  "_embedded": {
    "productEntities": [
      ...data...
    ]
  },
  "_links": {
    "first": {
      "href": "http://localhost:8080/products?page=0&size=20"
    },
    "self": {
      "href": "http://localhost:8080/products"
    },
    "next": {
      "href": "http://localhost:8080/products?page=1&size=20"
    },
    "last": {
      "href": "http://localhost:8080/products?page=4&size=20"
    }
  },
  "page": {
    "size": 20,
    "totalElements": 100,
    "totalPages": 5,
    "number": 0
  }
}

讓我們深入了解響應數據中的一些有趣事實

  • next 鏈接指向下一頁。last 鏈接指向的最后一個結果集。

  • self 鏈接提供整個系列。

  • 底部  page 提供有關分頁的信息,包括頁面大小,總結果,總頁數和當前頁碼。

4.2使用鏈接頭

HTTP標頭是REST API的關鍵方面.HTTP鏈接標頭還可用于將分頁信息傳遞給客戶端。通過上述測試,系統將返回以下附加信息作為Link HTTP標頭的一部分。

Link →<http://localhost:8080/products?page=0&size=20>; rel="first", <http://localhost:8080/products?page=1&size=20>; rel="next"

rel="next" 意思是下一頁是  page=2;rel="first" 意思是第一頁總是依賴page=2.于提供給你的這些鏈接關系。不要試圖猜測或構建自己的URL。Spring PagedResource提供所有這些信息作為結果的一部分,我們只需要確保從這些信息中構建正確的HTTP頭。在我們的控制器示例中,我們在createLinkHeader方法中構建標頭。

private String createLinkHeader(PagedResources < ProductEntity > pr) {
 final StringBuilder linkHeader = new StringBuilder();
 linkHeader.append(buildLinkHeader(pr.getLinks("first").get(0).getHref(), "first"));
 linkHeader.append(", ");
 linkHeader.append(buildLinkHeader(pr.getLinks("next").get(0).getHref(), "next"));
 return linkHeader.toString();
}

public static String buildLinkHeader(final String uri, final String rel) {
 return "<" + uri + ">; rel=\"" + rel + "\"";
}

以上就是如何在Spring中利用REST實現一個分頁功能,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

车险| 惠安县| 建瓯市| 交城县| 祥云县| 甘洛县| 内丘县| 朝阳县| 军事| 荥经县| 南皮县| 元朗区| 马尔康县| 南平市| 白玉县| 车险| 沂南县| 澎湖县| 东丰县| 信宜市| 兴义市| 运城市| 瑞金市| 芷江| 调兵山市| 新昌县| 湘潭县| 茶陵县| 招远市| 邹城市| 景德镇市| 平原县| 法库县| 土默特右旗| 东港市| 涿鹿县| 武冈市| 德庆县| 杭锦后旗| 满洲里市| 阿克陶县|