表征狀態(tài)傳輸(Representational State Transfer(REST) )是一個(gè)軟件架構(gòu)風(fēng)格,該架構(gòu)圍繞Http協(xié)議上數(shù)據(jù)的傳輸,使用http的那四個(gè)謂詞:get,put,serice.delete.這個(gè)架構(gòu)也避免了 對(duì)諸如:SOAP envelope這樣的附加包裝器的使用以及任何狀態(tài)數(shù)據(jù)的使用。
概要:REST是一個(gè)架構(gòu)風(fēng)格,首次在一個(gè)博士論文中被描述,該博士是Roy Fielding。在RESTful系統(tǒng)中,服務(wù)器利用URI暴露資源,客戶(hù)端使用四個(gè)Http謂詞來(lái)訪問(wèn)資源。由于客戶(hù)端接收了資源,他們被置于某種狀 態(tài)。當(dāng)他們?cè)L問(wèn)一個(gè)新的資源,通常是點(diǎn)擊下一個(gè)連接,他們改變了,或者說(shuō)是過(guò)渡了他們的狀態(tài)。為了工作,REST假設(shè)資源是能夠使用普遍的標(biāo)準(zhǔn)語(yǔ)法來(lái)代表 的。
3W網(wǎng)絡(luò)是最普及的例子,他是最大的基于REST策略構(gòu)建的系統(tǒng)。web瀏覽器作為客戶(hù)端訪問(wèn)駐留在web服務(wù)器上的資源。資源通過(guò)HTML或者xml體現(xiàn),所有的web瀏覽器可以消費(fèi)它。瀏覽器可以很容易的根據(jù)連接跳轉(zhuǎn)到新的資源上面。
RESTful系統(tǒng)的優(yōu)勢(shì)在于他們可以高伸縮性和高靈活性。因?yàn)楸辉L問(wèn)和操作的資源是通過(guò)http謂詞。資源通過(guò)URI被暴露,資源被通過(guò)標(biāo)準(zhǔn)的語(yǔ) 法體現(xiàn),客戶(hù)端不會(huì)被服務(wù)器所影響。也就是說(shuō),RESTFul系統(tǒng)可以充分體現(xiàn)http的可伸縮性特性,比如:緩存和代理特性。
基礎(chǔ)REST策略:RESTful架構(gòu)堅(jiān)持下面的基本原則:
資源:資源是REST的中心,一個(gè)資源是信息源,可以被URI來(lái)標(biāo)注的。在web的早期,資源是大量的靜態(tài)文檔,在當(dāng)下,一個(gè)資源可以是任何信息源,例如web Service可以是一個(gè)資源如果他能夠通過(guò)一個(gè)URI來(lái)被訪問(wèn)。
RESTful端點(diǎn)交換他們代表的資源。一個(gè)代表可以使一個(gè)包含了數(shù)據(jù)的文檔。例如:web Service的方法提供了訪問(wèn)客戶(hù)的記錄,那么該方法就是資源,在服務(wù)和消費(fèi)者之間傳輸?shù)目蛻?hù)信息拷貝,也是資源的代表。
REST最佳實(shí)踐:當(dāng)設(shè)計(jì)一個(gè)RESTful服務(wù)時(shí),最佳實(shí)踐有如下幫助:
例如:如果你在建立一個(gè)系統(tǒng),該系統(tǒng)處理駕駛記錄,每個(gè)記錄將有個(gè)唯一的URI,如果這個(gè)系統(tǒng)提供違規(guī)停車(chē)和超速罰款記錄,每個(gè)資源的類(lèi)型應(yīng)該也有一個(gè)唯一的基準(zhǔn)。例如:超速罰款應(yīng)該通過(guò)/speedingfines/driverID
來(lái)訪問(wèn),而違規(guī)停車(chē)應(yīng)該通過(guò)/parkingfines/
driverID
來(lái)訪問(wèn)。
放入去向別的資源的鏈接到應(yīng)答里,可以使客戶(hù)端跟從一個(gè)數(shù)據(jù)鏈變得容易。例如,如果你的服務(wù)返回一個(gè)資源集合,對(duì)于客戶(hù)單來(lái)說(shuō),更容易訪問(wèn)每個(gè)獨(dú)立的資 源,使用提供的連接,如果連接不被包含在response里面,客戶(hù)端需要附加的邏輯來(lái)跟從這個(gè)去向特定節(jié)點(diǎn)的連接。
需要客戶(hù)端或者服務(wù)端維護(hù)狀態(tài)信息,導(dǎo)致兩者的緊耦合,緊耦合會(huì)讓升級(jí)和遷移變得更困難。維護(hù)狀態(tài)也會(huì)使從通信錯(cuò)誤中還原狀態(tài)變得更麻煩。
設(shè)計(jì)一個(gè)RESTful web Service:
要執(zhí)行以下步驟:
一旦你定義好了服務(wù),你就可以使用FUSE Services Framework去實(shí)現(xiàn)它了。
采用Fuse Services Framework實(shí)現(xiàn)REST
FSF提供RESTful Web Service的java API的實(shí)現(xiàn)。JAX-RS提供標(biāo)準(zhǔn)的方式去映射POJO到資源中去,使用annotations。
當(dāng)從一個(gè)抽象的服務(wù)定義轉(zhuǎn)移到使用JAX-RS實(shí)現(xiàn)RESTFul Web Services實(shí)現(xiàn),你需要做:
1.創(chuàng)建根資源類(lèi)給資源,該根資源類(lèi)代表了服務(wù)資源樹(shù)的頂端。
2.映射服務(wù)的其他資源到樹(shù)的子資源節(jié)點(diǎn)上。
3.創(chuàng)建方法來(lái)實(shí)現(xiàn)每個(gè)http謂詞。
Data bindings:
默認(rèn)情況下,F(xiàn)SF使用JAXB對(duì)象來(lái)映射資源與他的java object。提供清晰,定義良好的映射,在對(duì)象和xml元素之間。
FSF實(shí)現(xiàn)也支持交換數(shù)據(jù)采用JSON,JSON是一種被Ajax開(kāi)發(fā)者廣泛使用的數(shù)據(jù)格式。在json和jaxb之間數(shù)據(jù)的編組被FSF運(yùn)行時(shí)動(dòng)態(tài)處理。
chapter2:創(chuàng)建資源
在RESTFul web Service中,所有的請(qǐng)求被資源所處理。JAX-RS API上實(shí)現(xiàn)了將資源看成java類(lèi)。一個(gè)資源類(lèi)是一個(gè)Java類(lèi),他被一個(gè)或多個(gè)RAX-RS注解所標(biāo)注。用JAX-RS實(shí)現(xiàn)的一個(gè)RESTFul web Service的核心是一個(gè)根資源類(lèi)。根資源類(lèi)是被暴露的服務(wù)的資源樹(shù)的入口點(diǎn)。他可以自己處理所有的請(qǐng)求,或者他可以提供對(duì)子起源的訪問(wèn)通道。
介紹:使用JAX-RS APIs實(shí)現(xiàn)的RESTFul WEb Services提供應(yīng)答作為資源代表,該代表實(shí)現(xiàn)了java類(lèi)。一個(gè)資源類(lèi)是一個(gè)類(lèi),該類(lèi)使用了JAX-RS注解來(lái)實(shí)現(xiàn)一個(gè)資源。對(duì)于大多數(shù) RESTful web services來(lái)說(shuō),他就是一個(gè)需要被訪問(wèn)的資源集合。資源類(lèi)的注解提供了信息諸如:資源的URI和每個(gè)操作處理的謂詞。
資源類(lèi)型:JAX-RS APIs允許你創(chuàng)建兩個(gè)基本類(lèi)型的資源:
例子:簡(jiǎn)單資源類(lèi):
package demo.jaxrs.server; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; @Path("/customerservice") public class CustomerService { public CustomerService() { } @GET public Customer getCustomer(@QueryParam("id") String id) { ... } ... }
基本的JAX-RS 注解
概述:
RESTful web service實(shí)現(xiàn)最最基本的信息片是:
JAX-RS定義了一組注解來(lái)提供基本的信息。所有的資源類(lèi)必須有至少一個(gè)注解。
設(shè)置路徑:
@path注解指明了一個(gè)資源的URI,該注解定義在Javax.ws.rs.Path接口中。它既可以用來(lái)包裝一個(gè)資源類(lèi),也可以用來(lái)包裝一個(gè)資 源的方法。它用一個(gè)字符串作為唯一參數(shù)(可參看上面的代碼)。該字符串是一個(gè)URI的形式,指明了被實(shí)現(xiàn)資源的location。
URI模板指明了資源的相對(duì)路徑,如下所示:模板包括
@Path("resourceName/{param1}/../{paramN}")
例如:URI模板:widgets/{color}/{number}將映射到widgets/blue/12.參數(shù)color的值是blue,number參數(shù)的值是12.
URI模板怎樣映射到一個(gè)完整的URI,依賴(lài)于@Path注解包裝的是什么東東,如果@path在根資源類(lèi)中(注解包裝的是根資源類(lèi)),那么URI模板是所有資源的根URI,并且他被直接添加到服務(wù)發(fā)布的URI中。如果注解是封裝一個(gè)子資源類(lèi),它將相對(duì)于根資源的URI。
指定HTTP 謂詞:JAX-RS使用五個(gè)注解來(lái)指定http謂詞,這些謂詞使用在方法上。
當(dāng)映射方法到http謂詞,你必須確保映射是有意義的。例如,入股你映射一個(gè)要提交訂單的方法,你應(yīng)當(dāng)映射他到一個(gè)put或者post謂詞。如果映射它到一個(gè)get或者delete謂詞,將導(dǎo)致不可以預(yù)計(jì)的情況發(fā)生。
根資源類(lèi):
概述:根資源類(lèi)是一個(gè)JAX-RS實(shí)現(xiàn)的RESTful服務(wù)的入口點(diǎn),它被@path包裝,指示出組成服務(wù)的所有資源的根URI。他的方法直接實(shí)現(xiàn)在資源上的操作或者提供一個(gè)訪問(wèn)其他子資源的通道。
需求:一個(gè)類(lèi)為了成為根資源類(lèi),它必須符合下面的規(guī)則:
指定的路徑是根URI對(duì)于所有實(shí)現(xiàn)服務(wù)的資源來(lái)說(shuō)。如果根資源類(lèi)指明它的路徑是wiggets并且一個(gè)方法實(shí)現(xiàn)了GET謂詞,然后一個(gè)在wedgets上 的GET調(diào)用將調(diào)用該方法。如果子資源指明了他的URI是{id},那么完整的URI模板對(duì)于子資源來(lái)說(shuō),就是widgets/{id},并且他將處理形 如widgets/12和widgets/42這樣的請(qǐng)求。
運(yùn)行環(huán)境必須能夠提供構(gòu)造器所需的所有參數(shù)。構(gòu)造器的參數(shù)可以包括被JAX-RS參數(shù)注解包裝的參數(shù)。
下例現(xiàn)實(shí)了一個(gè)根資源類(lèi)提供一個(gè)訪問(wèn)子資源類(lèi)的通道:
package demo.jaxrs.server; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Response; @Path("/customerservice/") public class CustomerService { public CustomerService() { ... } @GET public Customer getCustomer(@QueryParam("id") String id) { ... } @DELETE public Response deleteCustomer(@QueryParam("id") String id) { ... } @PUT public Response updateCustomer(Customer customer) { ... } @POST public Response addCustomer(Customer customer) { ... } @Path("/orders/{orderId}/") public Order getOrder(@PathParam("orderId") String orderId) { ... } }
resource 方法的工作原理
概述:資源方法被JAX-RS注解所注釋。他們有HTTP方法注解之一來(lái)指明方法處理哪種類(lèi)型的請(qǐng)求,JAX-RS放置了約束在資源方法上。
普通約束:所有的資源方法必須符合以下條件
參數(shù):資源方法參數(shù)采取兩種形式:
如下例:實(shí)現(xiàn)了一個(gè)資源方法,它具有有效的參數(shù)列
@POST @Path("disaster/monster/giant/{id}") public void addDaikaiju(Kaiju kaiju, @PathParam("id") String id) { ... }
如下例,實(shí)現(xiàn)了一個(gè)資源方法,他具有無(wú)效的參數(shù)列
@POST @Path("disaster/monster/giant/") public void addDaikaiju(Kaiju kaiju, String id) { ... }
返回值:資源方法可以返回以下類(lèi)型的值
所有的資源方法返回一個(gè)HTTP狀態(tài)代碼給請(qǐng)求端。當(dāng)方法的返回類(lèi)型是void或者返回值是null時(shí),資源方法設(shè)置狀態(tài)代碼為200,當(dāng)資源方法返回值不是null,它設(shè)置狀態(tài)值為204.
子資源的工作原理
概述:實(shí)際情況下,一個(gè)服務(wù)要處理很多資源。例如,在一個(gè)訂單處理服務(wù)的最佳實(shí)踐中,支持每個(gè)客戶(hù)作為唯一資源來(lái)被處理,每個(gè)訂單也作為唯一資源來(lái)被處理。
使用JAX-RS APIs,可以將客戶(hù)資源和訂單資源作為子資源來(lái)處理。一個(gè)子資源就是要通過(guò)根資源才能訪問(wèn)的資源。通過(guò)增加@path注解到一個(gè)類(lèi)方法來(lái)定義一個(gè)資源是子資源。子資源可以由兩條途徑來(lái)實(shí)現(xiàn):
說(shuō)明子資源:子資源通過(guò)用@path包裝一個(gè)方法來(lái)指明。子資源的URI結(jié)構(gòu)如下:
1.追加子資源的@path注解值到子資源的父資源的@path注解值后面。
父資源的@path注解也許被找到在資源類(lèi)的一個(gè)方法哪里,該方法返回一個(gè)對(duì)象,該對(duì)象包含了子資源。
2.重復(fù)前面的步驟直到根資源被觸及。
3.被組裝的URI被追加到基準(zhǔn)URI上。
@Conumes 和 @Produces
@Consumes
注釋代表的是一個(gè)資源可以接受的 MIME 類(lèi)型。@Produces
注釋代表的是一個(gè)資源可以返回的 MIME 類(lèi)型。這些注釋均可在資源、資源方法、子資源方法、子資源定位器或子資源內(nèi)找到。
@Consumes("application/json") @Produces("application/json")
聯(lián)系客服