2015年7月12日 星期日

JSP/Servlet中web.xml裡的<welcome-file>與Spring MVC的<mvc:resources>

在使用Spring框架時,如果在web.xml裡將所有的請求都交給Spring來處理的話,例如下面這樣:
<servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>2</load-on-startup>
    </servlet>
<servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
</servlet-mapping>

此時一些靜態資源可能就會因為沒有相應的Url Mapping或Controller來處理而無法回應靜態資源(如html, jpg, css, js等)的請求,這時我們可以有兩種方法來解決:
  1. 在Spring設定檔中,例如dispatcher-servlet.xml,加入如下內容,作用為再交由Spring的url mapping等處理之前,如果是靜態資源就交還給Web應用服務器管理:

  2. <mvc:default-servlet-handler />
    

  3.  在Spring設定檔中,加入以下內容,作用為對於符合"mapping"的靜態資源邏輯路徑(**表示任意子路徑),告知Web應用服務器去"location"的地方查找。例如對於以下設定,邏輯路徑為/resource/img/picture.jpg就會去找/img/picture.jpg:

  4. <mvc:resources location="/" mapping="/resource/**"/>
    
這裡要注意的地方是,如果我們有在web.xml裡設定歡迎頁面,例如像下面這樣:

<welcome-file-list>
        <welcome-file>index.html</welcome-file>
</welcome-file-list>

然後請求Web應用程式的根目錄時,例如 http://XXX.XXX.XXX.XXX/projectName ,根目錄的url請求,即 "/" ,會被Spring所接收處理,假設Spring設定檔中設定如下:

<mvc:resources location="/" mapping="/**"/>

根目錄 "/" 將會與mapping內容符合,並以location的值 "/" 返回給Web應用服務器,Web應用服務器發現為根目錄("/")的請求時,就會根據web.xml裡的歡迎頁面設定查找index.html。

也就是說,如果我們現在把index.html放在 "/html/index.html" 的路徑中,並且想要以http://XXX.XXX.XXX.XXX/projectName 的請求找到index.html的話,以下的設定方法是錯的



web.xml :
<welcome-file-list>
        <welcome-file>html/index.html</welcome-file>
</welcome-file-list>

dispatcher-servlet.xml :
<mvc:resources location="/html" mapping="/html/**"/>

會這樣設定可能的思路是想說http://XXX.XXX.XXX.XXX/projectName的請求發給Web應用服務器時,服務器會發出 "/html/index.html"的請求,被Spring接收後,符合mapping的值,並且叫Web應用服務器去"/html"下尋找index.html,想說應該可以找到index.html。

但就如上說明的,真正的情況是:
因為請求是http://XXX.XXX.XXX.XXX/projectName,即根目錄 "/" ,在welcome-file還沒被處理前,就已經先被Spring以以 "/" 的url接收,所以在mapping中完全找不到可以解析 "/" 的方法,故結果就是無法傳回網頁。

以下的方式才是正確的

<welcome-file-list>
        <welcome-file>html/index.html</welcome-file>
</welcome-file-list>

dispatcher-servlet.xml :
<mvc:resources location="/" mapping="/**"/>

當請求是http://XXX.XXX.XXX.XXX/projectName,即根目錄 "/" ,Spring會先接收處理,並發現與mapping中的值相符,並以location的值, "/" ,返回給Web應用服務器,此時應為Web應用服務器發現請求時根目錄,"/",就會去<welcome-file-list>裡去尋找<welcome-file>,並找到"/html/index.html"並正確返回頁面。

參考資料:

  1. mvc:resources in Spring MVC 3.1.2
  2. Spring MVC靜態資源處理
  3. springMVC使用html視圖配置詳解
  4. SpringMVC訪問靜態資源

沒有留言 :

張貼留言