日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

带有Spring的REST的ETag

發布時間:2023/12/3 javascript 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 带有Spring的REST的ETag 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.概述

本文將重點介紹ETags-Spring支持,RESTful API的集成測試以及帶有curl的使用場景。 這是關于使用Spring 3.1和Spring Security 3.1和基于Java的配置來建立安全的RESTful Web服務的系列文章的第9篇。

REST with Spring系列:

  • 第1部分 – 使用Spring 3.1和基于Java的配置引導Web應用程序
  • P藝術2 - 構建RESTful Web服務使用Spring 3.1和Java配置
  • P藝術3 - 保護RESTful Web服務使用Spring Security 3.1
  • 第4部分 – RESTful Web服務可發現性
  • 第5部分 – 使用Spring進行REST服務發現
  • 第6部分 – 使用Spring Security 3.1的RESTful服務的基本身份驗證和摘要身份驗證
  • 第7部分 – Spring的REST分頁
  • 第8部分 – 使用Spring Security對RESTful服務進行身份驗證

2. REST和ETag

從有關ETag支持的Spring官方文檔中:

ETag (實體標簽)是由HTTP / 1.1兼容的Web服務器返回的HTTP響應標頭,用于確定給定URL的內容更改。

ETag用于兩件事–緩存和條件請求。 ETag值可以是從Response主體的字節中計算得出的哈希值 。 因為很可能使用了加密哈希函數,所以即使是主體的最小修改也將極大地改變輸出,從而改變ETag的值。 這僅適用于強大的ETag-該協議的確也提供了較弱的Etag 。

使用If- *標頭會將標準GET請求轉換為條件GET 。 與ETag一起使用的兩個If- *標頭是“ If-None-Match ”和“ If-Match ” –各自具有自己的語義,如本文稍后所述。

3.使用

涉及ETag的簡單的Client-Server通信可以分為以下步驟:

首先 ,客戶端進行REST API調用–響應包括要存儲以供進一步使用的ETag標頭:

curl -H 'Accept: application/json' -i http://localhost:8080/rest-sec/api/resources/1HTTP/1.1 200 OK ETag: 'f88dd058fe004909615a64f01be66a7' Content-Type: application/json;charset=UTF-8 Content-Length: 52

–客戶端對RESTful API發出的下一個請求包括帶有上一步中的ETag值的If-None-Match請求標頭; 如果服務器上的資源未更改,則響應將不包含任何正文,并且狀態代碼為304 –未修改 :

curl -H 'Accept: application/json' -H 'If-None-Match: 'f88dd058fe004909615a64f01be66a7''-i http://localhost:8080/rest-sec/api/resources/1HTTP/1.1 304 Not Modified ETag: 'f88dd058fe004909615a64f01be66a7'

現在 ,在再次檢索資源之前,我們將通過執行更新來對其進行更改:

curl --user admin@fake.com:adminpass -H 'Content-Type: application/json' -i-X PUT --data '{ 'id':1, 'name':'newRoleName2', 'description':'theNewDescription' }' http://localhost:8080/rest-sec/api/resources/1HTTP/1.1 200 OK ETag: 'd41d8cd98f00b204e9800998ecf8427e' <strong>Content-Length: 0</strong>

最后 ,我們發出了最后一個請求以再次獲取特權; 請記住,自上次檢索以來已對其進行了更新,因此先前的ETag值將不再起作用-響應將包含新數據和新ETag,這些ETag可以再次存儲以備后用:

curl -H 'Accept: application/json' -H 'If-None-Match: 'f88dd058fe004909615a64f01be66a7'' -i http://localhost:8080/rest-sec/api/resources/1HTTP/1.1 200 OK ETag: '03cb37ca667706c68c0aad4cb04c3a211' Content-Type: application/json;charset=UTF-8 Content-Length: 56

一切就在這里– ETags狂野地節省了帶寬。

4. Spring對ETag的支持

對Spring的支持–在Spring中使用ETag非常容易設置,并且對于應用程序是完全透明的。 通過在web.xml中添加一個簡單的Filter來啟用該支持:

<filter><filter-name>etagFilter</filter-name><filter-class>org.springframework.web.filter.ShallowEtagHeaderFilter</filter-class> </filter> <filter-mapping><filter-name>etagFilter</filter-name><url-pattern>/api/*</url-pattern> </filter-mapping>

篩選器映射到與RESTful API本身相同的URI模式。 從Spring 3.0開始,過濾器本身就是ETag功能的標準實現。

該實現是一個淺層實現-根據響應計算ETag,這將節省帶寬,不能 節省 服務器性能 。 因此,將從ETag支持中受益的請求仍將作為標準請求進行處理,消耗其通常會消耗的任何資源(數據庫連接等),并且只有在將其響應返回給客戶端之前,ETag支持才會啟動在。

屆時,ETag將從響應主體中計算出來,并在資源本身上設置; 同樣,如果在請求中設置了If-None-Match標頭,則也會對其進行處理。

ETag機制的更深層實現可能會帶來更大的好處-例如為緩存中的某些請求提供服務,而根本不必執行計算-但這種實現絕非像淺層方法那樣簡單,也不可插入在這里描述。

5.測試ETag

讓我們開始簡單–我們需要驗證檢索單個Resource的簡單請求的響應是否實際上將返回“ ETag”標頭:

@Test public void givenResourceExists_whenRetrievingResource_thenEtagIsAlsoReturned() {// GivenResource existingResource = getApi().create(new Resource());String uriOfResource = baseUri + '/' + existingResource.getId();// WhenResponse findOneResponse = RestAssured.given().header('Accept', 'application/json').get(uriOfResource);// ThenassertNotNull(findOneResponse.getHeader(HttpHeaders.ETAG)); }

接下來我們驗證ETag行為的幸福路徑 –如果從服務器檢索資源的請求使用正確的ETag值,則不再返回資源。

@Test public void givenResourceWasRetrieved_whenRetrievingAgainWithEtag_thenNotModifiedReturned() {// GivenT existingResource = getApi().create(createNewEntity());String uriOfResource = baseUri + '/' + existingResource.getId();Response findOneResponse = RestAssured.given().header('Accept', 'application/json').get(uriOfResource);String etagValue = findOneResponse.getHeader(HttpHeaders.ETAG);// WhenResponse secondFindOneResponse= RestAssured.given().header('Accept', 'application/json').headers('If-None-Match', etagValue).get(uriOfResource);// ThenassertTrue(secondFindOneResponse.getStatusCode() == 304); }

一步步:

  • 首先創建資源 ,然后再檢索–保存ETag值以備將來使用
  • 發送新的檢索請求,這次使用“ If-None-Match ”標題指定先前存儲的ETag值
  • 在第二個請求上,服務器僅返回304 Not Modified ,因為資源本身在兩次檢索操作之間確實沒有被修改。

最后 ,我們驗證在第一個和第二個檢索請求之間更改資源的情況:

@Test public void givenResourceWasRetrieved_whenRetrievingAgainWithEtag_thenNotModifiedReturned() {// GivenT existingResource = getApi().create(createNewEntity());String uriOfResource = baseUri + '/' + existingResource.getId();Response findOneResponse = RestAssured.given().header('Accept', 'application/json').get(uriOfResource);String etagValue = findOneResponse.getHeader(HttpHeaders.ETAG);existingResource.setName(randomAlphabetic(6))getApi().update(existingResource.setName(randomString));// WhenResponse secondFindOneResponse= RestAssured.given().header('Accept', 'application/json').headers('If-None-Match', etagValue).get(uriOfResource);// ThenassertTrue(secondFindOneResponse.getStatusCode() == 200); }

一步步:

  • 首先創建資源 ,然后再檢索–保存ETag值以備將來使用
  • 然后更新相同的資源
  • 發送新的檢索請求,這次使用“ If-None-Match ”標題指定先前存儲的ETag值
  • 在第二個請求上,服務器將返回200 OK以及完整的Resource,因為ETag值不再正確,因為與此同時資源已更新

接下來 ,我們測試“ If-Match ”的行為– ShallowEtagHeaderFilter沒有為If-Match HTTP標頭提供開箱即用的支持(在此JIRA問題上進行了跟蹤),因此以下測試應失敗:

@Test public void givenResourceExists_whenRetrievedWithIfMatchIncorrectEtag_then412IsReceived() {// GivenT existingResource = getApi().create(createNewEntity());// WhenString uriOfResource = baseUri + '/' + existingResource.getId();Response findOneResponse = RestAssured.given().header('Accept', 'application/json').headers('If-Match', randomAlphabetic(8)).get(uriOfResource);// ThenassertTrue(findOneResponse.getStatusCode() == 412); }

一步步:

  • 首先創建資源
  • 然后使用“ If-Match ”標題檢索的資源指定了錯誤的ETag值-這是一個有條件的GET請求
  • 服務器應返回412前提條件失敗

6. ETag很大

我們僅將ETag用于讀取操作 – 存在RFC,試圖闡明實現方式應如何在寫入操作中處理ETag –這不是標準的,但很有趣。

當然,ETag機制還有其他可能的用途,例如用于使用Spring 3.1的樂觀鎖定機制以及處理相關的“丟失更新問題” 。

使用ETag時,還需要注意一些已知的潛在陷阱和警告 。

7.結論

本文僅介紹了Spring和ETags所能提供的功能。 要全面實現啟用了ETag的RESTful服務,以及用于驗證ETag行為的集成測試,請查看github項目 。

參考:來自badung博客的JCG合作伙伴 Eugen Paraschiv 提供的Spring的ETags 。

翻譯自: https://www.javacodegeeks.com/2013/01/etags-for-rest-with-spring.html

總結

以上是生活随笔為你收集整理的带有Spring的REST的ETag的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。