欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java中TESTful架構(gòu)原理分析

 更新時間:2021年09月09日 17:35:15   作者:蔡曉建  
這篇文章主要介紹了對java架構(gòu)中TESTful架構(gòu)原理進行了詳細的原理分析,有需要的朋友可以借鑒參考下,希望可以有所幫助,祝大家多多進步,早日升職加薪

1. 什么是REST

REST全稱是Representational State Transfer,中文意思是表述(編者注:通常譯為表征)性狀態(tài)轉(zhuǎn)移。 它首次出現(xiàn)在2000年Roy Fielding的博士論文中,Roy Fielding是HTTP規(guī)范的主要編寫者之一。 他在論文中提到:“我這篇文章的寫作目的,就是想在符合架構(gòu)原理的前提下,理解和評估以網(wǎng)絡(luò)為基礎(chǔ)的應用軟件的架構(gòu)設(shè)計,得到一個功能強、性能好、適宜通信的架構(gòu)。REST指的是一組架構(gòu)約束條件和原則?!?如果一個架構(gòu)符合REST的約束條件和原則,我們就稱它為RESTful架構(gòu)。

REST本身并沒有創(chuàng)造新的技術(shù)、組件或服務(wù),而隱藏在RESTful背后的理念就是使用Web的現(xiàn)有特征和能力, 更好地使用現(xiàn)有Web標準中的一些準則和約束。雖然REST本身受Web技術(shù)的影響很深, 但是理論上REST架構(gòu)風格并不是綁定在HTTP上,只不過目前HTTP是唯一與REST相關(guān)的實例。 所以我們這里描述的REST也是通過HTTP實現(xiàn)的REST。

2. 理解RESTful

要理解RESTful架構(gòu),需要理解Representational State Transfer這個詞組到底是什么意思,它的每一個詞都有些什么涵義。 下面我們結(jié)合REST原則,圍繞資源展開討論,從資源的定義、獲取、表述、關(guān)聯(lián)、狀態(tài)變遷等角度,列舉一些關(guān)鍵概念并加以解釋。

  • 資源與URI
  • 統(tǒng)一資源接口
  • 資源的表述
  • 資源的鏈接
  • 狀態(tài)的轉(zhuǎn)移

2. 1 資源與URI

REST全稱是表述性狀態(tài)轉(zhuǎn)移,那究竟指的是什么的表述? 其實指的就是資源。任何事物,只要有被引用到的必要,它就是一個資源。資源可以是實體(例如手機號碼),也可以只是一個抽象概念(例如價值) 。下面是一些資源的例子:

  • 某用戶的手機號碼
  • 某用戶的個人信息
  • 最多用戶訂購的GPRS套餐
  • 兩個產(chǎn)品之間的依賴關(guān)系
  • 某用戶可以辦理的優(yōu)惠套餐
  • 某手機號碼的潛在價值

要讓一個資源可以被識別,需要有個唯一標識,在Web中這個唯一標識就是URI(Uniform Resource Identifier)。 URI既可以看成是資源的地址,也可以看成是資源的名稱。如果某些信息沒有使用URI來表示,那它就不能算是一個資源, 只能算是資源的一些信息而已。URI的設(shè)計應該遵循可尋址性原則,具有自描述性,需要在形式上給人以直覺上的關(guān)聯(lián)。這里以github網(wǎng)站為例,給出一些還算不錯的URI:

https://github.com/git
https://github.com/git/git
https://github.com/git/git/blob/master/block-sha1/sha1.h
https://github.com/git/git/commit/e3af72cdafab5993d18fae056f87e1d675913d08
https://github.com/git/git/pulls
https://github.com/git/git/pulls?state=closed
https://github.com/git/git/compare/master…next

下面讓我們來看看URI設(shè)計上的一些技巧:

  • 使用_-來讓URI可讀性更好

曾經(jīng)Web上的URI都是冰冷的數(shù)字或者無意義的字符串,但現(xiàn)在越來越多的網(wǎng)站使用_或-來分隔一些單詞,讓URI看上去更為人性化。 例如國內(nèi)比較出名的開源中國社區(qū),它上面的新聞地址就采用這種風格, 如

http://www.oschina.net/news/38119/oschina-translate-reward-plan。

  • 使用/來表示資源的層級關(guān)系

例如上述/git/git/commit/e3af72cdafab5993d18fae056f87e1d675913d08就表示了一個多級的資源, 指的是git用戶的git項目的某次提交記錄,又例如/orders/2012/10可以用來表示2012年10月的訂單記錄。

  • 使用?用來過濾資源

很多人只是把?簡單的當做是參數(shù)的傳遞,很容易造成URI過于復雜、難以理解??梢园?#63;用于對資源的過濾, 例如/git/git/pulls用來表示git項目的所有推入請求,而/pulls?state=closed用來表示git項目中已經(jīng)關(guān)閉的推入請求, 這種URL通常對應的是一些特定條件的查詢結(jié)果或算法運算結(jié)果。

  • ,;可以用來表示同級資源的關(guān)系

有時候我們需要表示同級資源的關(guān)系時,可以使用,或;來進行分割。例如哪天github可以比較某個文件在隨意兩次提交記錄之間的差異或許可以使用/git/git /block-sha1/sha1.h/compare/e3af72cdafab5993d18fae056f87e1d675913d08;bd63e61bdf38e872d5215c07b264dcc16e4febca作為URI。

不過,現(xiàn)在github是使用…來做這個事情的,例如/git/git/compare/master…next。

2. 2 統(tǒng)一資源接口

RESTful架構(gòu)應該遵循統(tǒng)一接口原則,統(tǒng)一接口包含了一組受限的預定義的操作,不論什么樣的資源,都是通過使用相同的接口進行資源的訪問。接口應該使用標準的HTTP方法如GET,PUT和POST,并遵循這些方法的語義。

如果按照HTTP方法的語義來暴露資源,那么接口將會擁有安全性和冪等性的特性,例如GET和HEAD請求都是安全的, 無論請求多少次,都不會改變服務(wù)器狀態(tài)。而GET、HEAD、PUT和DELETE請求都是冪等的,無論對資源操作多少次, 結(jié)果總是一樣的,后面的請求并不會產(chǎn)生比第一次更多的影響。

下面列出了GET,DELETE,PUT和POST的典型用法:

GET

安全且冪等
獲取表示
變更時獲取表示(緩存)
200(OK) - 表示已在響應中發(fā)出
204(無內(nèi)容) - 資源有空表示
301(Moved Permanently) - 資源的URI已被更新
303(See Other) - 其他(如,負載均衡)
304(not modified)- 資源未更改(緩存)
400 (bad request)- 指代壞請求(如,參數(shù)錯誤)
404 (not found)- 資源不存在
406 (not acceptable)- 服務(wù)端不支持所需表示
500 (internal server error)- 通用錯誤響應
503 (Service Unavailable)- 服務(wù)端當前無法處理請求

POST

不安全且不冪等
使用服務(wù)端管理的(自動產(chǎn)生)的實例號創(chuàng)建資源
創(chuàng)建子資源
部分更新資源
如果沒有被修改,則不過更新資源(樂觀鎖)
200(OK)- 如果現(xiàn)有資源已被更改
201(created)- 如果新資源被創(chuàng)建
202(accepted)- 已接受處理請求但尚未完成(異步處理)
301(Moved Permanently)- 資源的URI被更新
303(See Other)- 其他(如,負載均衡)
400(bad request)- 指代壞請求
404 (not found)- 資源不存在
406 (not acceptable)- 服務(wù)端不支持所需表示
409 (conflict)- 通用沖突
412 (Precondition Failed)- 前置條件失?。ㄈ鐖?zhí)行條件更新時的沖突)
415 (unsupported media type)- 接受到的表示不受支持
500 (internal server error)- 通用錯誤響應
503 (Service Unavailable)- 服務(wù)當前無法處理請求

PUT

不安全但冪等
用客戶端管理的實例號創(chuàng)建一個資源
通過替換的方式更新資源
如果未被修改,則更新資源(樂觀鎖)
200 (OK)- 如果已存在資源被更改
201 (created)- 如果新資源被創(chuàng)建
301(Moved Permanently)- 資源的URI已更改
303 (See Other)- 其他(如,負載均衡)
400 (bad request)- 指代壞請求
404 (not found)- 資源不存在
406 (not acceptable)- 服務(wù)端不支持所需表示
409 (conflict)- 通用沖突
412 (Precondition Failed)- 前置條件失?。ㄈ鐖?zhí)行條件更新時的沖突)
415 (unsupported media type)- 接受到的表示不受支持
500 (internal server error)- 通用錯誤響應
503 (Service Unavailable)- 服務(wù)當前無法處理請求

DELETE

不安全但冪等
刪除資源
200 (OK)- 資源已被刪除
301 (Moved Permanently)- 資源的URI已更改
303 (See Other)- 其他,如負載均衡
400 (bad request)- 指代壞請求
404 (not found)- 資源不存在
409 (conflict)- 通用沖突
500 (internal server error)- 通用錯誤響應
503 (Service Unavailable)- 服務(wù)端當前無法處理請求

下面我們來看一些實踐中常見的問題:

  • POST和PUT用于創(chuàng)建資源時有什么區(qū)別?

POST和PUT在創(chuàng)建資源的區(qū)別在于,所創(chuàng)建的資源的名稱(URI)是否由客戶端決定。 例如為我的博文增加一個java的分類,生成的路徑就是分類名/categories/java,那么就可以采用PUT方法。不過很多人直接把POST、GET、PUT、DELETE直接對應上CRUD,例如在一個典型的rails實現(xiàn)的RESTful應用中就是這么做的。 我認為,這是因為rails默認使用服務(wù)端生成的ID作為URI的緣故,而不少人就是通過rails實踐REST的,所以很容易造成這種誤解。

  • 客戶端不一定都支持這些HTTP方法吧?

的確有這種情況,特別是一些比較古老的基于瀏覽器的客戶端,只能支持GET和POST兩種方法。 在實踐上,客戶端和服務(wù)端都可能需要做一些妥協(xié)。例如rails框架就支持通過隱藏參數(shù)_method=DELETE來傳遞真實的請求方法, 而像Backbone這樣的客戶端MVC框架則允許傳遞_method傳輸和設(shè)置X-HTTP-Method-Override頭來規(guī)避這個問題。

統(tǒng)一接口是否意味著不能擴展帶特殊語義的方法?

統(tǒng)一接口并不阻止你擴展方法,只要方法對資源的操作有著具體的、可識別的語義即可,并能夠保持整個接口的統(tǒng)一性。 像WebDAV就對HTTP方法進行了擴展,增加了LOCK、UPLOCK等方法。而github的API則支持使用PATCH方法來進行issue的更新,例如:

PATCH /repos/:owner/:repo/issues/:number

不過,需要注意的是,像PATCH這種不是HTTP標準方法的,服務(wù)端需要考慮客戶端是否能夠支持的問題。

  • 統(tǒng)一資源接口對URI有什么指導意義?

統(tǒng)一資源接口要求使用標準的HTTP方法對資源進行操作,所以URI只應該來表示資源的名稱,而不應該包括資源的操作。 通俗來說,URI不應該使用動作來描述。例如,下面是一些不符合統(tǒng)一接口要求的URI:

GET /getUser/1
POST /createUser
PUT /updateUser/1
DELETE /deleteUser/1

  • 如果GET請求增加計數(shù)器,這是否違反安全性?

安全性不代表請求不產(chǎn)生副作用,例如像很多API開發(fā)平臺,都對請求流量做限制。像github,就會限制沒有認證的請求每小時只能請求60次。 但客戶端不是為了追求副作用而發(fā)出這些GET或HEAD請求的,產(chǎn)生副作用是服務(wù)端“自作主張”的。 另外,服務(wù)端在設(shè)計時,也不應該讓副作用太大,因為客戶端認為這些請求是不會產(chǎn)生副作用的。

  • 直接忽視緩存可取嗎?

即使你按各個動詞的原本意圖來使用它們,你仍可以輕易禁止緩存機制。 最簡單的做法就是在你的HTTP響應里增加這樣一個報頭: Cache-control: no-cache。 但是,同時你也對失去了高效的緩存與再驗證的支持(使用Etag等機制)。 對于客戶端來說,在為一個REST式服務(wù)實現(xiàn)程序客戶端時,也應該充分利用現(xiàn)有的緩存機制,以免每次都重新獲取表示。

  • 響應代碼的處理有必要嗎?

HTTP的響應代碼可用于應付不同場合,正確使用這些狀態(tài)代碼意味著客戶端與服務(wù)器可以在一個具備較豐富語義的層次上進行溝通。 例如,201(“Created”)響應代碼表明已經(jīng)創(chuàng)建了一個新的資源,其URI在Location響應報頭里。 假如你不利用HTTP狀態(tài)代碼豐富的應用語義,那么你將錯失提高重用性、增強互操作性和提升松耦合性的機會。 如果這些所謂的RESTful應用必須通過響應實體才能給出錯誤信息,那么SOAP就是這樣的了,它就能夠滿足了。

2. 3 資源的表述

上面提到,客戶端通過HTTP方法可以獲取資源,是吧? 不,確切的說,客戶端獲取的只是資源的表述而已。 資源在外界的具體呈現(xiàn),可以有多種表述(或成為表現(xiàn)、表示)形式,在客戶端和服務(wù)端之間傳送的也是資源的表述,而不是資源本身。 例如文本資源可以采用html、xml、json等格式,圖片可以使用PNG或JPG展現(xiàn)出來。 資源的表述包括數(shù)據(jù)和描述數(shù)據(jù)的元數(shù)據(jù),例如,HTTP頭“Content-Type” 就是這樣一個元數(shù)據(jù)屬性。

那么客戶端如何知道服務(wù)端提供哪種表述形式呢?

答案是可以通過HTTP內(nèi)容協(xié)商,客戶端可以通過Accept頭請求一種特定格式的表述,服務(wù)端則通過Content-Type告訴客戶端資源的表述形式。

以github為例,請求某組織資源的json格式的表述形式:

假如github也能夠支持xml格式的表述格式,那么結(jié)果就是這樣的:

下面我們來看一些實踐上常見的設(shè)計:

在URI里邊帶上版本號

有些API在URI里邊帶上版本號,例如:

http://api.example.com/1.0/foo
http://api.example.com/1.2/foo
http://api.example.com/2.0/foo

如果我們把版本號理解成資源的不同表述形式的話,就應該只是用一個URL,并通過Accept頭部來區(qū)分,還是以github為例,它的Accept的完整格式是

application/vnd.github[.version].param[+json]

對于v3版本的話,就是Accept: application/vnd.github.v3。對于上面的例子,同理可以使用使用下面的頭部:

Accept: vnd.example-com.foo+json; version=1.0
Accept: vnd.example-com.foo+json; version=1.2
Accept: vnd.example-com.foo+json; version=2.0

使用URI后綴來區(qū)分表述格式

像rails框架,就支持使用/users.xml或/users.json來區(qū)分不同的格式。 這樣的方式對于客戶端來說,無疑是更為直觀,但混淆了資源的名稱和資源的表述形式。 我個人認為,還是應該優(yōu)先使用內(nèi)容協(xié)商來區(qū)分表述格式。

如何處理不支持的表述格式

當服務(wù)器不支持所請求的表述格式,那么應該怎么辦?若服務(wù)器不支持,它應該返回一個HTTP 406響應,表示拒絕處理該請求。下面以github為例,展示了一個請求XML表述資源的結(jié)果:

2. 4 資源的鏈接

我們知道REST是使用標準的HTTP方法來操作資源的,但僅僅因此就理解成帶CURD的Web數(shù)據(jù)庫架構(gòu)就太過于簡單了。 這種反模式忽略了一個核心概念:“超媒體即應用狀態(tài)引擎(hypermedia as the engine of application state)”。 超媒體是什么? 當你瀏覽Web網(wǎng)頁時,從一個連接跳到一個頁面,再從另一個連接跳到另外一個頁面,就是利用了超媒體的概念:把一個個把資源鏈接起來.

要達到這個目的,就要求在表述格式里邊加入鏈接來引導客戶端。在《RESTful Web Services》一書中,作者把這種具有鏈接的特性成為連通性。下面我們具體來看一些例子。

下面展示的是github獲取某個組織下的項目列表的請求,可以看到在響應頭里邊增加Link頭告訴客戶端怎么訪問下一頁和最后一頁的記錄。 而在響應體里邊,用url來鏈接項目所有者和項目地址。

又例如下面這個例子,創(chuàng)建訂單后通過鏈接引導客戶端如何去付款。

上面的例子展示了如何使用超媒體來增強資源的連通性。很多人在設(shè)計RESTful架構(gòu)時,使用很多時間來尋找漂亮的URI,而忽略了超媒體。所以,應該多花一些時間來給資源的表述提供鏈接,而不是專注于“資源的CRUD”。

2. 5 狀態(tài)的轉(zhuǎn)移

有了上面的鋪墊,再討論REST里邊的狀態(tài)轉(zhuǎn)移就會很容易理解了。 不過,我們先來討論一下REST原則中的無狀態(tài)通信原則。初看一下,好像自相矛盾了,既然無狀態(tài),何來狀態(tài)轉(zhuǎn)移一說?

其實,這里說的無狀態(tài)通信原則,并不是說客戶端應用不能有狀態(tài),而是指服務(wù)端不應該保存客戶端狀態(tài)。

2. 5.1 應用狀態(tài)與資源狀態(tài)

實際上,狀態(tài)應該區(qū)分應用狀態(tài)和資源狀態(tài),客戶端負責維護應用狀態(tài),而服務(wù)端維護資源狀態(tài)。 客戶端與服務(wù)端的交互必須是無狀態(tài)的,并在每一次請求中包含處理該請求所需的一切信息。 服務(wù)端不需要在請求間保留應用狀態(tài),只有在接受到實際請求的時候,服務(wù)端才會關(guān)注應用狀態(tài)。 這種無狀態(tài)通信原則,使得服務(wù)端和中介能夠理解獨立的請求和響應。 在多次請求中,同一客戶端也不再需要依賴于同一服務(wù)器,方便實現(xiàn)高可擴展和高可用性的服務(wù)端。

但有時候我們會做出違反無狀態(tài)通信原則的設(shè)計,例如利用Cookie跟蹤某個服務(wù)端會話狀態(tài),常見的像J2EE里邊的JSESSIONID。 這意味著,瀏覽器隨各次請求發(fā)出去的Cookie是被用于構(gòu)建會話狀態(tài)的。 當然,如果Cookie保存的是一些服務(wù)器不依賴于會話狀態(tài)即可驗證的信息(比如認證令牌),這樣的Cookie也是符合REST原則的。

2. 5.2 應用狀態(tài)的轉(zhuǎn)移

狀態(tài)轉(zhuǎn)移到這里已經(jīng)很好理解了, “會話”狀態(tài)不是作為資源狀態(tài)保存在服務(wù)端的,而是被客戶端作為應用狀態(tài)進行跟蹤的。客戶端應用狀態(tài)在服務(wù)端提供的超媒體的指引下發(fā)生變遷。服務(wù)端通過超媒體告訴客戶端當前狀態(tài)有哪些后續(xù)狀態(tài)可以進入。 這些類似“下一頁”之類的鏈接起的就是這種推進狀態(tài)的作用——指引你如何從當前狀態(tài)進入下一個可能的狀態(tài)。

3. 總結(jié)

現(xiàn)在廣東XXX版本、XXX等項目中均使用傳統(tǒng)的RPC、SOAP方式的Web服務(wù),而移動南方基地XXXX項目的后臺, 雖然采用了JSON格式進行交互,但還是屬于RPC風格的。本文從資源的定義、獲取、表述、關(guān)聯(lián)、狀態(tài)變遷等角度, 試圖快速理解RESTful架構(gòu)背后的概念。RESTful架構(gòu)與傳統(tǒng)的RPC、SOAP等方式在理念上有很大的不同,希望本文能對各位理解REST有所幫助。

以上就是java中TESTful架構(gòu)原理分析的詳細內(nèi)容,更多關(guān)于java中TESTful架構(gòu)原理的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java如何將實體類轉(zhuǎn)換成json并在控制臺輸出

    java如何將實體類轉(zhuǎn)換成json并在控制臺輸出

    這篇文章主要介紹了java如何將實體類轉(zhuǎn)換成json并在控制臺輸出問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • Spring一步到位精通攔截器

    Spring一步到位精通攔截器

    攔截器(Interceptor)是一種動態(tài)攔截方法調(diào)用的機制,在SpringMVC中動態(tài)攔截控制器方法的執(zhí)行。本文將詳細講講SpringMVC中攔截器的概念及入門案例,感興趣的可以嘗試一下
    2023-01-01
  • spring cloud gateway使用 uri: lb://方式配置時,服務(wù)名的特殊要求

    spring cloud gateway使用 uri: lb://方式配置時,服務(wù)名的特殊要求

    這篇文章主要介紹了spring cloud gateway使用 uri: lb://方式配置時,服務(wù)名的特殊要求,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12
  • MyBatis-Plus攔截器實現(xiàn)數(shù)據(jù)權(quán)限控制的示例

    MyBatis-Plus攔截器實現(xiàn)數(shù)據(jù)權(quán)限控制的示例

    本文主要介紹了MyBatis-Plus攔截器實現(xiàn)數(shù)據(jù)權(quán)限控制的示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-02-02
  • Spring Boot分頁方法定義示例

    Spring Boot分頁方法定義示例

    這篇文章主要為大家介紹了Spring Boot 分頁方法定義,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-09-09
  • Java基礎(chǔ)-Java變量的聲明和作用域

    Java基礎(chǔ)-Java變量的聲明和作用域

    這篇文章主要介紹了Java變量的聲明和作用域,變量其實就是內(nèi)存中的一個存儲空間,用來存儲數(shù)據(jù),具體的相關(guān)內(nèi)容,需要的小伙伴可以參考下面文章內(nèi)容
    2022-01-01
  • 使用Vert.x Maven插件快速創(chuàng)建項目的方法

    使用Vert.x Maven插件快速創(chuàng)建項目的方法

    這篇文章主要介紹了使用Vert.x Maven插件快速創(chuàng)建項目的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-09-09
  • Java判斷絕對值的方法總結(jié)

    Java判斷絕對值的方法總結(jié)

    在本文中作者為大家分享了兩種Java判斷絕對值的方法,對此有興趣的朋友可以和小編一起學習下。
    2018-02-02
  • springcloud config配置讀取優(yōu)先級過程詳解

    springcloud config配置讀取優(yōu)先級過程詳解

    這篇文章主要介紹了springcloud config配置讀取優(yōu)先級過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-09-09
  • Java使用EasyExcel動態(tài)添加自增序號列

    Java使用EasyExcel動態(tài)添加自增序號列

    本文將介紹如何通過使用EasyExcel自定義攔截器實現(xiàn)在最終的Excel文件中新增一列自增的序號列,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09

最新評論