1. 程式人生 > >spring MVC的困惑 url-pattern的/和/*有區別

spring MVC的困惑 url-pattern的/和/*有區別

今天在寫專案時發現一個spring 總是報org.springframework.web.servlet.DispatcherServlet noHandlerFound警告: No mapping found for HTTP request with URI [/myspring/WEB-INF/jsp/index.jsp] in DispatcherServlet with name 'spring' 錯誤,也就是找不到我的index.jsp 我程式碼用

@RequestMapping(value="/login2")
    public ModelAndView login2(){

        return new ModelAndView("index");
    }
這樣總是無法找到index.jsp,但是下面卻沒問題,不會報錯,
@RequestMapping(value ="/login")
    public @ResponseBody String login(){
        System.out.println("LLLLL");
        return "SSSSSS";
    }
最後查詢發現是web.xml配置檔案問題,把 url-pattern 值“/*”改為“/”如下
<servlet-mapping> 
<servlet-name>spring</servlet-name> 
<url-pattern>/*</url-pattern> 
</servlet-mapping> 
<servlet-mapping> 
<servlet-name>spring</servlet-name> 
<url-pattern>/</url-pattern> 
</servlet-mapping>

這樣就解決我的錯誤

所以我感覺url對映應該是

<url-pattern>/</url-pattern> 會匹配到/login這樣的路徑型url,不會匹配到模式為*.jsp這樣的字尾型url
<url-pattern>/*</url-pattern> 會匹配所有url:路徑型的和字尾型的url(包括/login,*.jsp,*.js和*.html等)

下面是找到關於servlet容器對url相關知識,感覺還不錯

一、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選擇對應的請求資源。如果應用定義了一個defaultservlet,則容器會將請求丟給default servlet(什麼是default servlet?後面會講)。

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

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

  二、url-pattern詳解

在web.xml檔案中,以下語法用於定義對映:

1) 以”/’開頭和以”/*”結尾的是用來做路徑對映的。

2) 以字首”*.”開頭的是用來做擴充套件對映的。

3)“/” 是用來定義default servlet對映的。

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

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