轉自: http://blog.163.com/zhangmihuo_2007/blog/static/27011075201453044959574?suggestedreading
如果你的DispatcherServlet攔截 *.do這樣的URL,就不存在訪問不到靜態資源的問題。如果你的DispatcherServlet攔截“/”,攔截了所有的請求,同時對*.js,*.jpg的訪問也就被攔截了。
通過上面url-pattern的配置,所有URL請求都將被Spring MVC的DispatcherServlet截獲。這樣的配置,會造成js文件、css文件、圖片文件等靜態資源無法訪問。
比如,你的jsp頁面引用了一個圖片和juqery:
|
<body>
<h3>圖片訪問</h3>
<img src="image/1.jpg">
</body> |
那么,很抱歉,運行會提示404錯誤,找不到圖片資源,因為SpringMVC把“image/1.jpg”也當做了一個請求連接,但這個請求連接我們並沒有。
解決方法:
1、spring.3.0.4以后版本提供的<mvc:resources />(推薦使用此方式)
a)首先,<mvc:resources />允許靜態資源放在任何地方,如WEB-INF目錄下、類路徑下等,你甚至可以將JavaScript 等靜態文件打到JAR包中。通過location屬性指定靜態資源的位置,由於location屬性是Resources類型,因此可以使用諸 如"classpath:"等的資源前綴指定資源位置。傳統Web容器的靜態資源只能放在Web容器的根路徑下,<mvc:resources />完全打破了這個限制。
b)其 次,<mvc:resources />依據當前著名的Page Speed、YSlow等瀏覽器優化原則對靜態資源提供優化。你可以通過cacheSeconds屬性指定靜態資源在瀏覽器端的緩存時間,一般可將該時間 設置為一年,以充分利用瀏覽器端的緩存。在輸出靜態資源時,會根據配置設置好響應報文頭的Expires 和 Cache-Control值。
在接收到靜態資源的獲取請求時,會檢查請求頭的Last-Modified值,如果靜態資源沒有發生變化,則直接返回303相應狀態碼,提示客戶端使用瀏覽器緩存的數據,而非將靜態資源的內容輸出到客戶端,以充分節省帶寬,提高程序性能。
在spring-servlet.xml中添加如下配置:
| <mvc:resources location="/image/" mapping="/image/**"/> |
或者:
| <mvc:resources location="/,classpath:/META-INF/image/" mapping="/image/**"/> |
以 上配置將Web根路徑"/"及類路徑下 /META-INF/image/ 的目錄映射為/image路徑。假設Web根路徑下擁有images、js這兩個資源目錄,在images下面有bg.gif圖片,在js下面有 test.js文件,則可以通過 /images/1.jpg這個靜態資源。
假設WebRoot還擁有images/bg1.gif 及 js/test1.js,則也可以在網頁中通過 /resources/images/bg1.gif 及 /resources/js/test1.js 進行引用。
也可以簡單配置WEB-INF/spring-servlet.xml如下:
|
<!-- 靜態資源訪問 -->
<mvc:resources location="/image/" mapping="/image/**"/>
<mvc:resources location="/js/" mapping="/js/**"/>
<mvc:resources location="/css/" mapping="/css/**"/> |
需要也別注意的是:使用此方式需要導入 org.springframework.web.servlet-3.1.4.RELEASE.jar包到WEB/lib目錄下,而且版本要大於3.0.4,否則,在開發環境下會產生對resources元素沒找到情況:
cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'mvc:resources'。
必須在運行環境下就沒有這個問題,這是3.0.4版的一個bug,會在3.0.5中更新spring-mvc-3.0.4.xsd。
2、激活Tomcat的defaultServlet來處理靜態文件
<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- 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>
要配置多個,每種文件配置一個
要寫在DispatcherServlet的前面, 讓defaultServlet先攔截,這個就不會進入Spring了,我想性能是最好的吧。
Tomcat, Jetty, JBoss, and GlassFish 默認 Servlet的名字 -- "default"
Google App Engine 默認 Servlet的名字 -- "_ah_default"
Resin 默認 Servlet的名字 -- "resin-file"
WebLogic 默認 Servlet的名字 -- "FileServlet"
WebSphere 默認 Servlet的名字 -- "SimpleFileServlet"
最后再說明一下,如何你的 DispatcherServlet 攔截 *.do 這樣的 URL,就不存上述問題了。
