淺析Servlet的url-pattern

       做了2年多的J2EE開發,今天在看博客的時候看到這句話如果你還不知道 web.xml 中一個請求和一個 servlet 是如何匹配到一起的,那麼請搜索一下 servlet 的文檔。這可不是亂說呀,有很多人就認爲 /xyz/*.do 這樣的匹配方式能有效”...我倒了j_0070.gif

      馬上做了相關測試,發現web.xml如下

<servlet>
    <servlet-name>test</servlet-name>
    <servlet-class>com.koa.servlet.TestServlet</servlet-class>
</servlet>
<servlet-mapping>
     <servlet-name>test</servlet-name>
     <url-pattern>/test/*.do</url-pattern>
</servlet-mapping>

      在啓動服務器時就報錯了。。。

Caused by: java.lang.IllegalArgumentException: Invalid <url-pattern> /test/*.do in servlet mapping

at org.apache.catalina.core.StandardContext.addServletMapping(StandardContext.java:3245)

at org.apache.catalina.core.StandardContext.addServletMapping(StandardContext.java:3220)

at org.apache.catalina.deploy.WebXml.configureContext(WebXml.java:1367)


       然後去搜索下關於請求是怎麼匹配servlet的

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

      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

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