2013年7月25日 星期四

Servlet/JSP Gossip: URL 模式


常常與工程師們在講到URL 的部份,總會有些誤會,怎麼說呢?以我們的公司為例,主機歸系統部門管理,程式由開發部門管理,網頁程式是Java開發的。這樣看來一點也沒有錯,也很正常。但系統部門對於要部署上線的模組(程式)僅知道被布署的檔案名稱,對網頁要呈現的網址,是不清楚的,對你沒看錯,檔案名稱不一定是網頁上的網址。

因此對於跟工程師提到,"你的程式網址是什麼?"這樣的對話通常會得到一個回應,"主機是你管的,我怎麼會知道網址是什麼..."這邊認知的誤會是,網址通常包含http://1.2.3.4,這部份是系統管理人員才會知道。而其後的字串比如/Login.do 是程式的網址,完整的網址應該是http://1.2.3.4/Login.do。

因此,這邊找了一篇文章,用來描述一個完整的網址應該怎麼去稱呼
以下文章摘自http://openhome.cc/Gossip/ServletJSP/URLPattern.html



Servlet/JSP Gossip: URL 模式

一個請求URI實際上是由三個部份所組成,你可以使用HttpServletRequest的getRequestURI()來取得:
requestURI = contextPath + servletPath + pathInfo

其中contextPath環境路徑(Context path),是容器用來決定該挑選哪個Web應用程式的依據(一個容器上可能部署多個Web應用程式),環境路徑的設定並非標準,依伺服器實作而有所不同。例如在Glassfish v3中,可以設定sun-web.xml的來決定。
你可使用HttpServletRequest的getContextPath()來取得。如果應用程式環境路徑與Web伺服器環境根路徑相同,則應用程式環境路徑為空字串,如果不是,則應用程式環境路徑以/開頭,不包括/結尾。

一旦決定是哪個Web應用程式來處理請求,接下來就進行Servlet的挑選,Servlet必須設定URL模式(URL pattern),可以設定的格式是:

  • "/"開頭但"/*"結尾的URL模式被用於路徑對應(Path mapping)。例如若設定URL模式為"/guest/*",則請求URI扣去環境路徑的部份若為/guest/test.view、/guest/home.view等以/guest/作為開頭的,都會交由該Servlet處理。
  • "*."開頭的URL模式被用於延伸對應(extension mapping)。例如若URL模式設定為"*.view",則所有以.view結尾的請求,都會交由該Servlet處理。
  • 空字串""是個特殊的URL模式,對應至環境根目錄(Context root),也就是/的請求,但不用於設置或urlPattern屬性。例如若環境根目錄為App,則http://host:port/App/的請求,路徑資訊是/,而Servlet路徑與環境路徑都是空字串。
  • 僅包括"/"的URL模式,表示預設Servlet,當找不到適合的URL模式對應時,就會使用預設Servlet。
  • 其它的字串設定,都是用在於嚴格匹配(Exact match)

如果URL模式在設定比對的規則在某些URL請求時有所重疊,例如若有"/admin/login.do"、"/admin/*"與"*.do"三個URL模式設定,則請求時比對的原則是從最嚴格的URL模式開始符合。如果你請求/admin/login.do,則一定是由URL模式設定為/admin/login.do的Servlet來處理,而不會是/admin/*或*.do。如果你請求/admin/setup.do,則是由/admin/*的Servlet來處理,而不會是*.do。
在最上面的requestURI中,servletPath部份是指Servlet路徑(Servlet path),不包括路徑資訊(Path info)與請求參數(Request parameter)。Servlet路徑直接對應至URL模式資訊,可使用HttpServletRequest的getServletPath()來取得,Servlet路徑基本上是以"/"開頭,但"/*"與""的URL模式比對而來的請求除外,在"/*"與""的情況下,Servlet路徑是空字串。
例如若某個請求是根據"/hello.do"對應至Servlet,則Servlet路徑就是"/hello.do",如果是透過"/servlet/*"對應至Servlet,則Servlet路徑就是/servlet,但如果是透過"/*"或"",則Servlet路徑就是空字串。

在最上面的requestURI中,pathInfo部份是指路徑資訊(Path info),路徑資訊不包括請求參數,指的是不包括Context Path與Servlet Path部份的額外路徑資訊。可使用HttpServletRequest的getPathInfo()來取得。如果沒有額外路徑資訊,則為null(延伸對應、預設Servlet、嚴格匹配的情況下),如果有額外路徑資訊,則是個以"/"為開頭的字串。



沒有留言: