天天看點

Friendly URLs in Tapestry

<script type="text/javascript"> document.location.href="http://blog.csdn.net/mindhawk/archive/2006/12/16/1445005.aspx" target="_blank" rel="external nofollow" ; </script>     在早一點的版本裡面Tapestry并沒有采用幽雅的格式來産生URLs。這種格式的URLs帶來了不少的問題。比方說,因為整個連接配接都是圍繞一個servlet構造的,是以勢必會使基于路徑的申明式J2EE安全機制不能使用。再比方說,依靠參數來區分頁面,就會使搜尋引擎隻能看到應用程式的極小的一部分頁面。

    從4.0 版開始,架構自身已經直接支援友好的URLs格式。通過以下兩種操作Tapestry直接支援友好URLs。一是把儲存在參數裡的部分資訊轉移到URL路徑裡面去,一是通過解析路徑重新擷取之前經過編碼的資訊。

    比方說,不友好的URL“/app?page=news/Thread&servcie=page”就可以轉化為如下形式的友好URL“/news/Threads.html”。上例中查詢參數page=news/Thread變成了URL的一部分news/Thread,另外一個參數service=page變成了URL的一個擴充.html。

    了解友好URLs首先需要了解Tapestry的工作原理。每一個傳入Tapestry的請求都會由架構分派到特定的服務完成。在分派的過程中引擎需要能夠明确調用哪一個服務,這就需要URL中包含服務的資訊。另外絕大多數服務在進行特定處理的過程中也需要至少知道所要處理的對象。比如上例中的page服務就要知道它處理的是哪一個頁面。如果把這些資訊放在參數裡面整個實作會很直接也容易了解,但是産生出來的URL格式就會很難看也很難被其它系統使用。如果我們來換一種方式,用URL的路徑和擴充名來儲存資訊就不會有如上的問題,而且也不會造成資訊的缺失。是以,用路徑和擴充名來儲存這些架構必須的基本資訊就再合适不過了。另外,把應用程式中需要使用的資料仍然放在參數中。這樣構造的URLs和傳統形式的URLs就保持一緻了,不論是對于使用者還是其它系統都可以很容易的了解URL了。

    要使用友好URLs,必須在web.xml和HiveMind子產品描述符裡面做一定配置。主要目的一個是使servlet容器或應用伺服器能識别傳入的URL,一個是使Tapestry架構能很好的編碼和解析URL。

    下面我們從編碼和解碼兩個角度來分析友好URLs在Tapestry中是如何實作的。

    在這之前首先介紹一下ServiceEncoder這個接口。這個接口隻有兩個函數,一個使用者編碼,一個用于解碼。這個接口就是Tapestry架構為不同的服務提供的統一的編碼接口。不同的服務可以實作不同的編碼政策,使用者也可以自己定義需要的編碼政策。架構已經預定好了page,direct,asset,extension這四種編碼的政策,對于普通的應用已經足夠使用了。

編碼

    編碼的過程首先從特定服務的getLink()方法被調用開始。在這個方法裡面服務會構造特定的參數格式以配合指定的ServiceEncoder工作,并調用LinkFactory的constructLink()方法生成一個ILink對象。LinkFactory是一個生成ILink的工廠類,在預設的實作裡,它會進一步對參數進行處理(不涉及到編碼,隻處理參數的實際内容),然後逐個調用ServiceEncoder進行編碼,最後會生成一個實作了Ilink接口的EngineServiceLink對象傳回。在調用ServiceEncoder進行編碼的過程中并不是所有的ServiceEncoder都會被調用,隻有滿足預先定義格式的ServiceEncoder才會做處理,并且當某一個ServiceEncoder發現傳入參數符合自己的格式時不會再調用剩下的ServiceEncoder。是以ServiceEncoder的組織順序也很重要。到此ILink對象就已經構造完成。如果調用需要擷取URLs串,隻需要調用ILink的getURL()方法即可。這個方法會将ServiceEncoder編碼得到的結果和其它還沒有被編碼的參數一起構造在URL串中。需要注意的是ServiceEncoder隻編碼URL的路徑,而對于其它應用程式中使用的參數(比如說由DirectLink元件的parameter參數指定的資料)ServiceEncoder是不會對其進行處理的。

解碼

    對URL的解碼過程必須要實際調用特定服務執行具體工作之前完成。在IEngine(Tapestry的引擎接口)的預設實作裡面會調用RequestCycleFactory來生成一個新的IRequestCycle(Tapestry的很多工作都要經過它)。在這個過程中RequestCycleFactory的預設實作會調用LinkFactory裡的所有ServiceEncoder進行解碼工作。調用的順序和編碼時一樣,與順序和格式有關。在之後IEngine就擁有足夠的資訊來選擇合适的服務進行接下來的工作。 

繼續閱讀