servlet的匹配規(guī)則
1梭灿、url參與匹配的是哪部分
在介紹servlet的匹配規(guī)則之前画侣,先要說(shuō)明一點(diǎn),匹配的時(shí)候并不是用完整的url來(lái)和'<servlet-mapping>'中的'<url-pattern>'進(jìn)行匹配堡妒。
而是用完整url減去當(dāng)前應(yīng)用的上下文的路徑之后的部分來(lái)和'<url-pattern>'進(jìn)行匹配配乱。
舉個(gè)例子,譬如涕蚤,
請(qǐng)求的url是: 'http://localhost:8080/appDemo/user/users.html'
該應(yīng)用是appDemo宪卿,那么當(dāng)前應(yīng)用的上下文路徑是: 'http://localhost:8080/appDemo'
那么相減之后的部分就是: '/user/users.html' ,也就是用相減之后的這一部分與`<url-pattern>`進(jìn)行匹配。
2万栅、 servlet的四種匹配規(guī)則
● 精確匹配 :<url-pattern>中配置的項(xiàng)與url相應(yīng)部分完全一致才能匹配上佑钾。
● 路徑匹配:以/字符開(kāi)頭,并以/*結(jié)尾的字符串用于路徑匹配烦粒。
例如
①休溶、
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/user/*</url-pattern>
</servlet-mapping>
路徑以/user/開(kāi)始代赁,后面的路徑可以任意。比如下面的url都會(huì)被匹配:
http://localhost:8080/appDemo/user/users.html
http://localhost:8080/appDemo/user/addUser.action
http://localhost:8080/appDemo/user/updateUser.actionl
②兽掰、
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
【/*】它涵蓋的范圍最大芭碍,它可以匹配所有的request請(qǐng)求。
● 擴(kuò)展名匹配 :以*.開(kāi)頭的字符串被用于擴(kuò)展名匹配孽尽。
例如: <servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>*.jsp</url-pattern> //任何擴(kuò)展名為jsp的url請(qǐng)求都會(huì)匹配
</servlet-mapping>
● 缺省匹配:缺省匹配的寫(xiě)法是唯一的窖壕,就是<url-pattern>/</url-pattern>。
3杉女、匹配優(yōu)先級(jí)別
精確匹配 > 路徑匹配 > 擴(kuò)展名匹配 > 缺省匹配
4瞻讽、路徑匹配和擴(kuò)展名匹配不能同時(shí)使用
【注意】: <url-pattern>/aa/*/bb</url-pattern> //這個(gè)是精確匹配,url必須是/aa/*/bb熏挎,這里的*不是通配的含義
/ 速勇、/* 的區(qū)別
1、<url-pattern>/</url-pattern>屬于servlet中一種特殊的匹配模式坎拐。該模式有且只有一個(gè)實(shí)例烦磁,且優(yōu)先級(jí)別最低,不會(huì)覆蓋其他的url-pattern哼勇,
只會(huì)替換servlet容器中內(nèi)建的default servlet都伪,該模式同樣會(huì)匹配所有的請(qǐng)求。
2猴蹂、而servlet院溺,通常是配成<url-pattern>/</url-pattern>,這樣就只會(huì)匹配形如/login這樣的路徑型的url磅轻,而不會(huì)匹配到模式為*.jsp這樣的
后綴型url珍逸。之所以jsp頁(yè)面不會(huì)命中這個(gè)servlet,是因?yàn)閟ervlet容器內(nèi)建的JSP Servlet會(huì)被調(diào)用聋溜,而這個(gè)JSP Servlet設(shè)置的匹配規(guī)則是.jsp谆膳,
而由于擴(kuò)展名匹配的優(yōu)先級(jí)高于缺省匹配,因此輪不到缺省匹配的servlet去處理模式為*.jsp這樣的后綴型url撮躁。
3漱病、servlet如果配成<url-pattern>/*</url-pattern>,就很可能會(huì)出問(wèn)題把曼。因?yàn)檫@樣的servlet會(huì)攔截所有的請(qǐng)求杨帽,而且請(qǐng)求會(huì)在此servlet中結(jié)束,
也就是說(shuō)輪不到其他serevlet來(lái)處理請(qǐng)求嗤军。模式為*.jsp或*.js這樣的后綴型url也會(huì)被匹配到注盈,因此當(dāng)瀏覽器請(qǐng)求一個(gè)js資源的時(shí)候,也會(huì)被該
servlet攔截叙赚,最后會(huì)由于在控制器中找不到對(duì)應(yīng)的處理方法老客,而報(bào)404這樣的錯(cuò)誤僚饭。
4、而filter胧砰,因?yàn)樘幚砭幋a問(wèn)題的過(guò)濾器是要涵蓋所有的請(qǐng)求的鳍鸵,因此要使用路徑匹配中能涵蓋所有請(qǐng)求的<url-pattern>*/</url-pattern>。
<url-pattern>/</url-pattern>只在servlet中才會(huì)匹配所有的請(qǐng)求尉间。
interceptor偿乖、filter、servlet的匹配比較
★ springmvc的DispatcherServlet通常是配為:
<url-pattern>/</url-pattern>:表示攔截除靜態(tài)資源外的所有請(qǐng)求乌妒。
★ filter過(guò)濾器通常是配為:
<url-pattern>/*</url-pattern>:表示攔截所有請(qǐng)求(包括靜態(tài)資源)汹想。
★ 要注意的是,SpringMVC的interceptor攔截器的匹配規(guī)則和上面servlet的匹配規(guī)則是不一樣的撤蚊。
<mvc:mapping path="/document/*"/>
<mvc:mapping path="/document/**"/>
前者攔截的是/document/save或者/document/delete,而不能攔截/document/path1/save损话。 即只可以攔截當(dāng)前目錄下的所有請(qǐng)求
而后者攔截的是/document/save或者/document/path1/save或者/document/path1/path2/save侦啸,即可以攔截當(dāng)前目錄及其子目錄下的所有請(qǐng)求。
interceptor丧枪、filter光涂、servlet的對(duì)比
1、所在位置:servlet拧烦、filter忘闻、listener是配置到web.xml中,interceptor不配置到web.xml中恋博,struts的攔截器配置到struts.xml中齐佳,
spring的攔截器配置到spring.xml中。
2债沮、加載順序:web.xml 的加載順序是:context- param -> listener -> filter -> servlet
3炼吴、interceptor和filter的執(zhí)行順序:接收到http請(qǐng)求時(shí)先執(zhí)行filter再執(zhí)行interceptor,
最后返回html代碼前先執(zhí)行interceptor再執(zhí)行filter疫衩。
如果把整個(gè)請(qǐng)求看做生產(chǎn)流水線硅蹦,那么filter是在頭部和尾部,而interceptor是在脖子部位和膝蓋部位闷煤。