JAX-RS 從傻逼到牛叉 1:REST 基礎(chǔ)知識(shí)
Posted on 2011-09-16 15:31 蜀山兆孨龘 閱讀(5473) 評(píng)論(3) 編輯 收藏 所屬分類(lèi): Java EE 、SOAJAX-RS(JSR 311 - Java™ API for RESTful Web Services,用于 REST 風(fēng)格的 Web 服務(wù)的 Java™ API)是 Java EE 6 規(guī)范的一部分,其目標(biāo)在于簡(jiǎn)化和標(biāo)準(zhǔn)化用 Java 開(kāi)發(fā) REST 風(fēng)格的 Web 服務(wù)。雖然 Java EE 6 剛出爐的時(shí)候,樓主也從頭到尾看過(guò)這份規(guī)范,但苦于沒(méi)有實(shí)際的項(xiàng)目練手,看過(guò)又忘了,現(xiàn)在最多算達(dá)到大成傻逼的境界。這次邊看邊寫(xiě),期望完成后至少能破入小成牛逼。先從 REST 本身開(kāi)始。
REST(REpresentational State Transfer,代表性狀態(tài)傳輸)自稱(chēng)是一種風(fēng)格而非標(biāo)準(zhǔn),這在樓主看來(lái)有炒作的嫌疑。如果僅僅是一種風(fēng)格,那么不同的框架如何兼容?所以才有 JAX-RS 的誕生。REST 最大的貢獻(xiàn)是帶來(lái)了 HTTP 協(xié)議的復(fù)興。為什么叫復(fù)興呢?本來(lái) HTTP 的功能挺豐富的,可惜長(zhǎng)期以來(lái)只被用作傳輸數(shù)據(jù),大好青年被埋沒(méi)了。樓主記得剛開(kāi)始學(xué) Servlet 的時(shí)候,一向是把 doGet
和 doPost
兩個(gè)方法一視同仁的,因?yàn)闀?shū)上這么教,很多 Web 框架也這么搞,以至于弄了很久才搞清楚 GET
和 POST
是兩種不同的請(qǐng)求。現(xiàn)在 REST 拍磚說(shuō)道,HTTP 早就定義好了一堆操作,以前一直被混淆使用,現(xiàn)在應(yīng)該重新賦予它們本來(lái)的意義了,而且如果充分發(fā)揮 HTTP 的功能,完全能夠勝任分布式應(yīng)用的開(kāi)發(fā)(傳說(shuō)中的 SOA)。
SOA 的理念在于將系統(tǒng)設(shè)計(jì)為一系列可重用的、解耦的、分布式的服務(wù)。這也不是新鮮玩意兒了,早期有 CORBA,稍晚有 SOAP 等等。REST 作為后起之秀,能夠快速崛起,也必有其非同尋常的特色。下面一一列舉。
可尋址性(Addressability)
系統(tǒng)中的每個(gè)資源都可以通過(guò)唯一標(biāo)識(shí)符來(lái)訪(fǎng)問(wèn)。小插一句,“標(biāo)識(shí)”的正確讀音是 biāozhì。REST 使用 URI(統(tǒng)一資源標(biāo)識(shí)符)管理資源的地址。URI 的概念不解釋。一個(gè) URI 可以指向一個(gè)或者多個(gè)資源。
統(tǒng)一的受限接口(The Uniform, Constrained Interface)
實(shí)際上強(qiáng)調(diào)了 HTTP 操作的原意。REST 主要使用了 GET、PUT、DELETE、POST、HEAD 和 OPTIONS 這 6 種操作。此處有兩個(gè)曾經(jīng)被忽略的 HTTP 概念:冪等(idempotent)和安全(safe)。冪等應(yīng)該是 HTTP 從數(shù)學(xué)借來(lái)的一個(gè)術(shù)語(yǔ)(原始的數(shù)學(xué)意義樓主也不懂),意味著若干次請(qǐng)求的副作用與單次請(qǐng)求相同,或者根本沒(méi)有副作用。GET、PUT、DELETE、HEAD 和 OPTIONS 都是冪等的:GET、HEAD 和 OPTIONS 都是讀操作,容易理解;PUT 用于創(chuàng)建或更新已知 URI 的資源,多次創(chuàng)建或更新同一個(gè)資源顯然和一次的效果相同;DELETE 刪除資源,亦然。安全表示操作不會(huì)影響服務(wù)器的狀態(tài)。GET、HEAD 和 OPTIONS 是安全的。POST 既不冪等又不安全,因?yàn)楹?PUT 不同,POST 創(chuàng)建資源的時(shí)候并不知道資源的 URI,所以多個(gè) POST 請(qǐng)求將會(huì)創(chuàng)建多個(gè)資源。
面向表象(Representation-Oriented)
表象這個(gè)詞有點(diǎn)拗口,傳聞在一個(gè) REST 風(fēng)格的系統(tǒng)中,服務(wù)端和客戶(hù)端之間傳輸?shù)倪诉司褪潜硐蟆硐罂梢允羌兾谋?、XML、JSON……或者自編的山寨格式。唉,不就是數(shù)據(jù)么?只不過(guò)可以用任意的格式來(lái)傳輸,因?yàn)?HTTP 正文里面啥都能放。Content-Type
頭用來(lái)聲明格式,一般是 MIME(多用途因特網(wǎng)郵件擴(kuò)展),像 text/plain
、text/html
、application/pdf
這些。MIME 可以帶屬性,例如 text/html; charset=UTF-8
。
無(wú)態(tài)通信(Communicate Statelessly)
REST 服務(wù)器只管理資源,而不會(huì)像 Web 服務(wù)器一樣記錄客戶(hù)的會(huì)話(huà)狀態(tài),這些應(yīng)該由客戶(hù)端來(lái)管理,如此就能增強(qiáng) REST 服務(wù)器的伸縮性。此處的客戶(hù)端可以是客戶(hù)端程序、瀏覽器,甚至一個(gè) Web 應(yīng)用??傊?,REST 只負(fù)責(zé)庫(kù)管啦!
HATEOAS
猛詞砸來(lái)了!HATEOAS = Hypermedia As The Engine Of Application State,超媒體作為應(yīng)用狀態(tài)的引擎,怎么看起來(lái)比 SaaS(Software as a Service,軟件作為服務(wù))還要嚇人呢?超文本不過(guò)是一只紙老虎,超媒體也瞞不過(guò)樓主的天眼:超媒體就是是由文字、圖像、圖形、視頻、音頻……鏈成一體的大雜燴!很簡(jiǎn)單的一個(gè)例子,有些坑爹的電影網(wǎng)站經(jīng)常發(fā)布一些內(nèi)嵌了廣告的電影,播放的時(shí)候會(huì)彈出廣告窗口,里面很多鏈接,你去點(diǎn)兩下就中招了:這個(gè)電影文件就算是超媒體。
其實(shí)這個(gè)詞最關(guān)鍵的地方是“狀態(tài)引擎”。例如樓主在去網(wǎng)購(gòu),先選了幾個(gè)東西,接下來(lái)可以干啥呢?可以繼續(xù)選、可以把購(gòu)物車(chē)清空、可以結(jié)賬……樓主可以從現(xiàn)狀“轉(zhuǎn)換”到其他某些狀態(tài),而控制狀態(tài)轉(zhuǎn)換的那個(gè)咚咚就被冠名為狀態(tài)引擎。多么聰明的詞匯?。侵靼l(fā)現(xiàn)凡是高手都是造詞磚家呀!用超媒體來(lái)控制狀態(tài)轉(zhuǎn)換,就是 HATEOAS:你是要繼續(xù)看電影還是看廣告?看哪個(gè)廣告?自己慢慢考慮……
REST 相比 CORBA、SOAP、WS-* 之流確實(shí)獨(dú)樹(shù)一幟,但也難逃玩弄概念的嫌疑。記得大學(xué)里講數(shù)據(jù)庫(kù)的老師說(shuō)過(guò):“你們現(xiàn)在學(xué)了這么多理論,其實(shí)以后在工作中未必管用。在大街上隨便找一個(gè)軟件培訓(xùn)學(xué)校出來(lái)的小伙子,他哪兒懂什么第二第三范式啊?但卻能把數(shù)據(jù)庫(kù)玩兒得飛轉(zhuǎn)!”