在上一篇中我們初識(shí)了Servlet,相信大家對(duì)Servlet也都有了些了解,知道了如何創(chuàng)建一個(gè)Servlet,并且為其添加虛擬映射,最終發(fā)布項(xiàng)目,并在瀏覽器上請(qǐng)求對(duì)應(yīng)的Servlet。
十年的潁東網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開(kāi)發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。全網(wǎng)整合營(yíng)銷推廣的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整潁東建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無(wú)論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。成都創(chuàng)新互聯(lián)公司從事“潁東網(wǎng)站設(shè)計(jì)”,“潁東網(wǎng)站推廣”以來(lái),每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。
我們知道,只有給Servlet配置好虛擬路徑,客戶端才可以進(jìn)行訪問(wèn),但是對(duì)于Servlet的路徑映射,真的只有現(xiàn)在所知的這么簡(jiǎn)單么?
答案當(dāng)時(shí)是No了,不然怎么會(huì)有這篇文章😝,下面讓我們一起來(lái)探究其中的秘密吧!
Servlet虛擬路徑映射
在web.xml文件中,一個(gè)
1.配置多個(gè)映射路徑
在上一文中,我們說(shuō)到@WebServlet中的urlPatterns屬性,其可以是一組匹配規(guī)則,也就是說(shuō)一個(gè)Servlet是可以配置多個(gè)虛擬路徑的,也就是Servlet和虛擬路徑可以是一對(duì)多的一個(gè)關(guān)系(并不是多對(duì)多,一個(gè)虛擬路徑只能映射一個(gè)Servlet),其具體實(shí)現(xiàn)如下,并修改doPost處的代碼:
@WebServlet( description = "My First Servlet", urlPatterns = { "/HelloServlet", "/StillMe" }, initParams = { @WebInitParam(name = "name", value = "lizishu") }) public class HelloServlet extends HttpServlet { //具體邏輯參看上篇文章 //... protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //設(shè)置返回客戶端的contentType //text/plain :純文本格式 設(shè)置為text/html println的換行會(huì)失效 response.setContentType("text/plain;charset=utf-8"); //response.setCharacterEncoding("utf-8"); PrintWriter out = response.getWriter(); out.println("Served at: " + request.getContextPath()); String name = this.getInitParameter("name"); out.println("name: " + name); out.println("訪問(wèn)的Servle名為:" + HelloServlet.class); } }
可以看到,增加一個(gè)虛擬路徑映射非常方便,只需在urlPatterns中新增一項(xiàng)即可(注意'/'不可省略),啟動(dòng)項(xiàng)目,在瀏覽器上輸入url,可以看到,無(wú)論是輸入http://localhost:8080/FirstProject/HelloServlet、還是http://localhost:8080/FirstProject/StillMe頁(yè)面上得到的輸出內(nèi)容均一致。
urlPatterns在Servlet 3.0版本之前,都是配置在web.xml中的,每個(gè)Servlet會(huì)有一個(gè)對(duì)應(yīng)的
標(biāo)簽,其中可以配置多個(gè)
。
2.urlPatterns匹配規(guī)則
說(shuō)到Servlet虛擬路勁的匹配規(guī)則,還需要說(shuō)到urlPatterns的幾種匹配規(guī)則,主要有以下四種:
需要注意的是,路徑匹配和擴(kuò)展匹配無(wú)法混合使用,即urlPattern無(wú)法寫成"/rest/*.do";這也是讓部分同學(xué)感到困惑的地方,Servlet的虛擬路徑匹配并不是完全的按照正則來(lái)匹配的,雖然路徑匹配和擴(kuò)展匹配是按照正則中的通配符(*)來(lái)匹配的,這也是部分同學(xué)可以會(huì)寫出特定的正則,但是卻不是一個(gè)合法的虛擬路徑;Servlet容器收到請(qǐng)求后,會(huì)將請(qǐng)求從上下文路徑(通過(guò)request.getContextPath()獲取的)處截?cái)?,使用剩余的部分?lái)進(jìn)行路徑匹配,比如請(qǐng)求url為http://localhost:8080/FirstProject/HelloServlet,那么Servlet容器就會(huì)使用"/HelloServlet"來(lái)匹配Servlet。
最后需要注意的是,我們說(shuō)了上面四種匹配規(guī)則,尤其是缺省匹配,可以匹配到任意請(qǐng)求,那么一個(gè)請(qǐng)求如果可以匹配多個(gè)Servlet的虛擬路徑,那么該執(zhí)行哪個(gè)Servlet?其實(shí)啊,這些匹配規(guī)則是有優(yōu)先級(jí)的,具體的優(yōu)先級(jí)為:精確匹配>路徑匹配>擴(kuò)展名匹配>缺省匹配,Servlet容器會(huì)從優(yōu)先級(jí)高的虛擬路徑開(kāi)始匹配,匹配到后就會(huì)立刻將請(qǐng)求交給對(duì)應(yīng)的Servlet來(lái)處理,不會(huì)再關(guān)心其他Servlet的虛擬路徑是否會(huì)匹配成功。
下面我們來(lái)一組Servlet及其對(duì)應(yīng)的虛擬路徑:
urlPatterns | Servlet Name |
---|---|
/abc/* | Servlet1 |
/ | Servlet2 |
/abc | Servlet3 |
*.do | Servlet4 |
當(dāng)請(qǐng)求去除上下文路徑后路徑為:"/abc/a.html"時(shí),根據(jù)上述規(guī)則,會(huì)調(diào)用Servlet1;
請(qǐng)求為:"/abc",根據(jù)匹配優(yōu)先級(jí),會(huì)調(diào)用Servlet3;
請(qǐng)求為:"/abc/a.do",會(huì)匹配到'/abc/*'、'*.do',但根據(jù)匹配優(yōu)先級(jí),會(huì)調(diào)用Servlet1;
請(qǐng)求為:"/a.do",會(huì)匹配到'/'、'*.do',但根據(jù)匹配優(yōu)先級(jí),會(huì)調(diào)用Servlet4;
3.Tomcat提供的缺省Servlet
為了測(cè)試缺省Servlet,我們來(lái)進(jìn)行一個(gè)測(cè)試。我們新建個(gè)SelfDefaultServlet,其urlPatterns我們配置為"/",其中的方法我們不做任何修改。
@WebServlet( description = "Self create default Servlet", urlPatterns = { "/" } ) public class SelfDefaultServlet extends HttpServlet { //... }
我們啟動(dòng)項(xiàng)目后,在瀏覽器上輸入http://localhost:8080/FirstProject/hahaha或者其他任意無(wú)法匹配到HelloServlet虛擬路徑的請(qǐng)求,發(fā)現(xiàn)頁(yè)面上的結(jié)果都如下所示,是不是這樣也不錯(cuò),不會(huì)報(bào)404錯(cuò)誤了。
但是,此時(shí)我們想訪問(wèn)WebContent目錄下的靜態(tài)頁(yè)面(新建的一個(gè)welcome.html文件),瀏覽器上輸入http://localhost:8080/FirstProject/welcome.html,猜猜會(huì)發(fā)生什么?我們來(lái)一起看下結(jié)果,如圖所示,請(qǐng)求結(jié)果并沒(méi)有按照我們的想法,根據(jù)請(qǐng)求路徑找到welcome.htm頁(yè)面,而是調(diào)用了SelfDefaultServlet,是不是很懵?
其實(shí),客戶端的每個(gè)請(qǐng)求,都是由Servlet容器根據(jù)虛擬路徑的匹配規(guī)則來(lái)進(jìn)行處理的,包括靜態(tài)資源。并且,如果路徑輸入錯(cuò)誤(去除了自己配置的缺省Servlet后),我們常見(jiàn)的下面的錯(cuò)誤,也是Servlet返回給我們,哈哈,還是很意外?
我們能通過(guò)servlet方便簡(jiǎn)單的開(kāi)發(fā)網(wǎng)站,是因?yàn)槲覀冋驹诹司奕说募绨蛏?,下面我們一起?lái)看下Sun公司都為我們開(kāi)發(fā)者提前做了些什么工作。Tomcat會(huì)為項(xiàng)目配置一個(gè)缺省的Servlet(如果項(xiàng)目中自行配置,則不會(huì)生效),配置文件在tomcat安裝目錄下conf目錄中的web.xml文件中,具體內(nèi)容如下,缺省的Servlet名為DefaultServlet。
default org.apache.catalina.servlets.DefaultServlet debug 0 listings false 1 default /
客戶端請(qǐng)求靜態(tài)資源文件時(shí),也是由缺省的Servlet處理的(自己?jiǎn)为?dú)配置Servlet除外),如果請(qǐng)求文件能找到,就會(huì)將頁(yè)面通過(guò)HttpServletResponse對(duì)象以流的方式返回給客戶端,否則報(bào)404錯(cuò)誤。
不過(guò)講到這里,大家可以自己試一試配置了缺省Servelt時(shí),訪問(wèn)welcome.html的情況(會(huì)調(diào)用SelfDefaultServlet),但是,如果我們?cè)跒g覽器中輸入http://localhost:8080/FirstProject/index.jsp(index.jsp是創(chuàng)建的第一個(gè)jsp頁(yè)面)呢?會(huì)是什么樣一個(gè)結(jié)果?也是調(diào)用缺省的Servlet么?真是的運(yùn)行結(jié)果如下:
這是什么原因?為什么不是調(diào)用缺省的servlet了?這是因?yàn)閠omcat除了缺省Serlvet外,還給我們提供一個(gè)處理jsp文件的Servlet,配置如下,因?yàn)楹缶Y匹配的優(yōu)先級(jí)高于缺省的Servlet,所以訪問(wèn)JSP的時(shí)候需要交由JspServlet來(lái)處理(JSP因?yàn)榭赡馨琂ava代碼,所以第一次執(zhí)行的時(shí)候需要先編譯,這個(gè)工作由JspServlet完成)
jsp org.apache.jasper.servlet.JspServlet fork false xpoweredBy false 3 jsp *.jsp *.jspx
4.總結(jié)
本文具體討論了urlPatterns屬性的匹配規(guī)則,主要為四種,其優(yōu)先級(jí)也各不相同,我們?cè)谑褂脮r(shí),也需要根據(jù)自己的需求自己設(shè)定urlPatterns,不過(guò)知道了匹配規(guī)則,使用起來(lái)也會(huì)方便很多,也能幫我們快速的定位錯(cuò)誤。
到此這篇關(guān)于Servlet虛擬路徑映射配置詳解的文章就介紹到這了,更多相關(guān)Servlet 虛擬路徑映射內(nèi)容請(qǐng)搜索創(chuàng)新互聯(lián)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持創(chuàng)新互聯(lián)!