OK!現(xiàn)在已經(jīng)可以使用這個(gè)action了。當(dāng)然,這還需要瀏覽器客戶端的支持。當(dāng)你的客戶端以GET來(lái)請(qǐng)求/article/2007/8/a001 時(shí),struts2就會(huì)調(diào)用ArticleAction的view方法,而PUT請(qǐng)求則會(huì)對(duì)應(yīng)到update方法,DELETE請(qǐng)求會(huì)對(duì)應(yīng)到remove 方法... 但是,如果你的客戶端只支持GET和POST怎么辦?Restful2ActionMapper的文檔中提到:To simulate the HTTP methods PUT and DELETE, since they aren't supported by HTML, the HTTP parameter "__http_method" will be used.對(duì)于只支持GET和POST的傳統(tǒng)網(wǎng)頁(yè),我們可以增加一個(gè)"__http_method"參數(shù)來(lái)模擬PUT和DELETE,比如:POST /article/2007/8/a001&__http_method=DELETE。隨著Javascript和Ajax框架的發(fā)展,我們已 經(jīng)可以使用PUT和DELETE等方法。Ajax使用XmlHttpRequest進(jìn)行操作時(shí),在發(fā)送請(qǐng)求之前,可以通過設(shè)置RequestType的方 式來(lái)完成對(duì)請(qǐng)求方法的設(shè)定。 三、不足之處Restful2ActionMapper對(duì)REST風(fēng)格的支持是不完全的。在REST風(fēng)格中,我們可以使用同一個(gè)URI來(lái)獲取同一個(gè)資源的多種表現(xiàn)形 式。在發(fā)送HTTP請(qǐng)求時(shí),只要我們?cè)谡?qǐng)求頭中指定一個(gè)Accept參數(shù),那么服務(wù)器就可以通過判斷該參數(shù)來(lái)決定返回什么類型的數(shù)據(jù)。如果Accept為 text/xml,服務(wù)器會(huì)返回xml格式的數(shù)據(jù),如果Accept為text/json,則會(huì)返回json格式的數(shù)據(jù),但URI是固定的。而 Restful2ActionMapper只是作了URI的映射,并沒有考慮返回?cái)?shù)據(jù)的格式問題。要讓struts2支持完全的REST風(fēng)格,我們不得不 對(duì)它進(jìn)行改造,或者,等待它的改進(jìn)。另外,Restful2ActionMapper所定義的URL映射規(guī)則也有一個(gè)小小的“陷阱”。比如,GET /user/1表示讀取id為1的user,但按照Restful2ActionMapper的定義,/user/new會(huì)對(duì)應(yīng)到action的 editNew方法,如果這個(gè)"new"就是某個(gè)用戶的id呢?為了避開這個(gè)陷阱,我寧愿使用/user/!editNew這種丑陋的形式。事實(shí)上,隨著 客戶端技術(shù)的發(fā)展,我們完全可以不使用editNew方法而構(gòu)造輸入頁(yè)面,然后向服務(wù)器發(fā)送POST來(lái)創(chuàng)建資源。同樣,edit方法也不是必要的。 (注:我修改后的Restful2ActionMapper去除了/user/new這種形式的映射) 四、其它有個(gè)struts2的插件,叫jsonplugin,可以讓struts2很方便地支持json輸出。而Adobe Spry Framework、YUI-ext、DOJO等都能很好地支持json,并能很好地支持HTTP的各種請(qǐng)求方法。我推薦struts2的用戶使用 jsonplugin和Adobe Spry Framework或YUI-ext(或其它UI Framework)。Struts2只輸出json格式的結(jié)果(最好還能輸出xml),而UI和數(shù)據(jù)裝配交給Adobe Spry/YUI-ext等去做。這樣的組合會(huì)讓你更好更方便地使用REST風(fēng)格。五、修改后的Restful2ActionMapper這里我附上修改后的Restful2ActionMapper,大家可以在此基礎(chǔ)上進(jìn)行擴(kuò)充。比如,我前面提到Restful2ActionMapper 不能根據(jù)Accept請(qǐng)求頭來(lái)返回不同格式的數(shù)據(jù),其實(shí)也是可以進(jìn)行改進(jìn)的。我看到已經(jīng)有人在讀過我這篇文章后提出一種方案,類似于這樣的:/user/a001/xml => 返回xml格式的result /user/a001/json => 返回json格式的result /user/a001/... 這是一種辦法,另外,根據(jù)url的擴(kuò)展名來(lái)做,也是一種辦法。但是這都不是好方案!我前面已經(jīng)提過,按照REST風(fēng)格,一個(gè)Web應(yīng)用總是使用固定的 URI向外部世界呈現(xiàn)(或者說暴露)一個(gè)資源,而前面這兩種方案只是使URL友好點(diǎn)而已,并不真正符合REST風(fēng)格。當(dāng)然,這樣也不錯(cuò)了,也是不錯(cuò)的方 案,其實(shí)ROR中也有類似的做法。 但我們還有更好的方案,我提個(gè)思路,然后大家自行對(duì)Restful2ActionMapper進(jìn)行改進(jìn): 在Action中可以設(shè)置一個(gè)consumeMime屬性,并寫好對(duì)應(yīng)的getter/setter方法。在Restful2ActionMapper返 回mapping之前,提取request的Accept頭信息,然后將該信息放到mapping.params之中。action的各個(gè)method最 后只返回consumeMime,這樣就可以在action的配置文件中按consumeMime來(lái)配置result了。 下面,附上修改后的Restful2ActionMapper代碼: java 代碼
|
聯(lián)系客服