1. 程式人生 > >Web.xml中設定Servlet和Filter時的url-pattern匹配規則

Web.xml中設定Servlet和Filter時的url-pattern匹配規則

① 完全匹配 /test/list.do
② 目錄匹配 /test/* 
③ 副檔名匹配 *.do servlet-mapping的重要規則: 
     ☆ 容器會首先查詢完全匹配,如果找不到,再查詢目錄匹配,如果也找不到,就查詢副檔名匹配。 

     ☆ 如果一個請求匹配多個“目錄匹配”,容器會選擇最長的匹配。

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

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

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

其匹配規則和順序如下: 
     1. 精確路徑匹配。例子:比如servletA 的url-pattern為 /test,servletB的url-pattern為 /* ,這個時候,如果我訪問的url為http://localhost/test ,這個時候容器就會先 進行精確路徑匹配,發現/test正好被servletA精確匹配,那麼就去呼叫servletA,也不會去理會其他的servlet了。 
     2. 最長路徑匹配。例子:servletA的url-pattern為/test/*,而servletB的url-pattern為/test/a/*,此時訪問http://localhost/test/a時,容器會選擇路徑最長的servlet來匹配,也就是這裡的servletB。 
     3. 擴充套件匹配,如果url最後一段包含擴充套件,容器將會根據擴充套件選擇合適的servlet。例子:servletA的url-pattern:*.action 
     4. 如果前面三條規則都沒有找到一個servlet,容器會根據url選擇對應的請求資源。如果應用定義了一個default servlet,則容器會將請求丟給default servlet.

     根據這個規則表,就能很清楚的知道servlet的匹配過程,所以定義servlet的時候也要考慮url-pattern的寫法,以免出錯。 對於filter,不會像servlet那樣只匹配一個servlet,因為filter的集合是一個鏈,所以只會有處理的順序不同,而不會出現只選擇一個filter。Filter的處理順序和filter-mapping在web.xml中定義的順序相同。

二,url-pattern詳解 在web.xml檔案中,以下語法用於定義對映: 
l 以”/’開頭和以”/*”結尾的是用來做路徑對映的。 
l 以字首”*.”開頭的是用來做擴充套件對映的。 
l “/” 是用來定義default servlet對映的。 
l 剩下的都是用來定義詳細對映的。比如: /aa/bb/cc.action

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

一般做全匹配時,servlet的url-pattern 為 / 。filter的url-pattern 為 /* 。
/和/*之間的區別:
<url-pattern>/</url-pattern>: 會匹配到/login這樣的路徑型url,不會匹配到模式為*.jsp這樣的字尾型url
<url-pattern>/*</url-pattern>:會匹配所有url:路徑型的和字尾型的url(包括/login , *.jsp , *.js 和 *.html 等)
<url-pattern>/</url-pattern>: 甚至會造成The requested resource () is not available.
參考一個博文連結: