轉一好東西

轉自:http://foxty.iteye.com/blog/39332

Servlet和Filter的url匹配以及url-pattern詳解

Servlet filter J2EE 開發中常用的技術,使用方便,配置簡單,老少皆宜。估計大多數朋友都是直接配置用,也沒有關心過具體的細節,今天遇到一個問題,上網查了 servlet 的規範才發現, servlet filter 中的 url-pattern 還是有一些文章在裏面的,總結了一些東西,放出來供大家參考,以免遇到問題又要浪費時間。 <o:p></o:p>

    一, servlet 容器對 url 的匹配過程: <o:p></o:p>

      <o:p></o:p>

當一個請求發送到 servlet 容器的時候,容器先會將請求的 url 減去當前應用上下文的 路徑 作爲 servlet 的映射 url ,比如我訪問的是 http://localhost/test/aaa.html ,我的應用上下文是 test ,容器會將 http://localhost/test 去掉,剩下的 /aaa.html 部分拿來做 servlet 的映射匹配。這個映射匹配過程是有順序的,而且當有一個 servlet 匹配成功以後,就不會去理會剩下的 servlet 了( filter 不同,後文會提到)。其匹配規則和順序如下: <o:p></o:p>

1.     精確路徑匹配。例子:比如 servletA url-pattern /test servletB url-pattern /* ,這個時候,如果我訪問的 url http://localhost/test ,這個時候容器就會先 進行精確路徑匹配,發現 /test 正好被 servletA 精確匹配,那麼就去調用 servletA ,也不會去理會其他的 servlet 了。 <o:p></o:p>

2.     最長路徑匹配。例子: servletA url-pattern /test/* ,而 servletB url-pattern /test/a/* ,此時訪問 http://localhost/test/a 時,容器會選擇路徑最長的 servlet 來匹配,也就是這裏的 servletB <o:p></o:p>

3.     擴展匹配,如果 url 最後一段包含擴展,容器將會根據擴展選擇合適的 servlet 。例子: servletA url-pattern *.action<o:p></o:p>

4.     如果前面三條規則都沒有找到一個 servlet ,容器會根據 url 選擇對應的請求資源。如果應用定義了一個 default servlet ,則容器會將請求丟給 default servlet (什麼是 default servlet ?後面會講) <o:p></o:p>

      根據這個規則表,就能很清楚的知道 servlet 的匹配過程,所以定義 servlet 的時候也要考慮 url-pattern 的寫法,以免出錯。 <o:p></o:p>

      對於 filter ,不會像 servlet 那樣只匹配一個 servlet ,因爲 filter 的集合是一個鏈,所以只會有處理的順序不同,而不會出現只選擇一個 filter Filter 的處理順序和 filter-mapping web.xml 中定義的順序相同。 <o:p></o:p>

    二,url-pattern 詳解 <o:p></o:p>

         web.xml 文件中,以下語法用於定義映射:

l  ”/’ 開頭和以 ”/*” 結尾的是用來做路徑映射的。

l  以前綴 ”*.” 開頭的是用來做擴展映射的。

l  “/” 是用來定義 default servlet 映射的。

l  剩下的都是用來定義詳細映射的。比如: /aa/bb/cc.action

所以,爲什麼定義 ”/*.action” 這樣一個看起來很正常的匹配會錯?因爲這個匹配即屬於路徑映射,也屬於擴展映射,導致容器無法判斷。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章