SpringMVC對靜態資源的處理

Tomcat和應用處理請求的級別和流程如下圖所示:

對資源的訪問地址爲:http://ip:port/應用名/資源名

1:根據ip和port確定是哪個tomcat。

2:根據應用名確定是哪個應用。

3:根據資源名來確定訪問哪個資源。

4:如果web.xml配置的DispatcherServlet的攔截路徑是“*.do/*.action”,則springmvc不會處理靜態資源的請求,靜態資源的請求最終還是交由tomcat的默認Servlet來處理。(tomcat的默認Servlet的作用:首先所有的請求進入tomcat,其次進入應用,然後開始遍歷應用中配置的Servlet的攔截路徑,如果沒有匹配到應用指定的所有servlet路徑,那麼就會流到默認的servlet。)

5:如果web.xml配置的DispatcherServlet的攔截路徑是“/”,則springmvc也會處理對靜態資源的請求,這樣就會出現問題。

問題描述:

如果在配置DispatcherServlet的時候,攔截 *.do或者*.action這樣的URL,由於不會攔截對*.jpg,*.css,*.js等靜態資源的訪問,所以靜態資源的請求最終交由Tomcat的默認Servlet來處理,就不會出現訪問不到靜態資源的問題。但是如果在配置DispatcherServlet時攔截“/”,攔截了所有的請求,即同時攔截了對*.js,*.jpg的訪問,則會出現找不到靜態資源文件,報404錯誤。

方案一:讓Tomcat的defaultServlet來處理靜態文件。(在springmvc攔截到對靜態資源的訪問之前搶先用默認Servlet攔截到對靜態資源的訪問)

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.jpg</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.js</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.css</url-pattern>
</servlet-mapping>  
要配置多個servlet-mapping,每種類型文件配置一個;要寫在DispatcherServlet的前面, 讓defaultServlet先攔截,這樣對靜態資源文件的請求就不會進入SpringMVC了。

各種web服務器默認Servlet的名字如下:
Tomcat, Jetty, JBoss, and GlassFish  默認 Servlet的名字 -- "default"
Google App Engine 默認 Servlet的名字 -- "_ah_default"
Resin 默認 Servlet的名字 -- "resin-file"
WebLogic 默認 Servlet的名字  -- "FileServlet"

默認的Servlet爲什麼能處理靜態請求呢?

方案二: 使用<mvc:resources /> (在springmvc攔截到對靜態資源的訪問之後,由springmvc對靜態資源特殊處理)

<mvc:resources/> 的使用方法:
<!--對靜態資源文件的訪問-->
<mvc:resources mapping="/images/**" location="/images/" />
在mapping屬性配置頁面文件中對靜態資源的請求路徑,在location屬性配置靜態資源存放的目錄。

 mapping屬性會將符合條件的請求映射到 ResourceHttpRequestHandler 進行處理,最終從location指定的目錄中找到靜態資源,並向客戶端做出響應。

方案三 :使用<mvc:default-servlet-handler/>(在springmvc攔截到對靜態資源的訪問之後,再將靜態資源交由默認Servlet進行處理)

在Spring MVC 的配置文件中提供了一個<mvc:default-servlet-handler/>標籤。在 WEB 容器啓動的時候會在上下文中定義一個 DefaultServletHttpRequestHandler,它會對DispatcherServlet的請求進行處理(即被DispatcherServlet攔截的請求下一步會經過DefaultServletHttpRequestHandler);如果該請求已經作了映射,那麼會接着交給後臺對應的處理程序;如果沒有作映射,就交給 WEB 應用服務器默認的 Servlet 處理(即Tomcat默認的Servlet),從而找到對應的靜態資源;只有再找不到資源時纔會報錯。

和方案一中說的一樣,某些 WEB 應用服務器默認的 Servlet的名字是 default。如果默認 Servlet 用不同名稱自定義配置,或者在缺省 Servlet 名稱未知的情況下使用了不同的 Servlet 容器,則必須顯式提供默認 Servlet 的名稱,如下:

<mvc:default-servlet-handler default-servlet-name="myCustomDefaultServlet"/>

這都是在xml中配置的情況,應該還有使用JavaConfig配置的情況,待總結……

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