什么是靜態資源?
css、js、圖片、html等都是靜態資源
1. 放行靜態資源
1、不使用 springmvc 框架分析
不使用 springmvc 框架,這些靜態資源請求都會由 tomcat 的默認的 default 進行處理。
2、使用了 springmvc 框架分析
當配置的 DispatcherServlet 的映射路徑不為 / 時,對靜態資源的請求最終會由 tomcat 的默認配置來處理,所以不影響靜態資源的正常訪問。
如果配置的 DispatcherServlet 的映射路徑為 / 時,會覆蓋掉tomcat的默認的 default 配置,所以需要在 springmvc 文件中進行配置,對靜態資源進行放行。
1)在 springmvc.xml 中放行 - 需要開啟 <mvc:annotation-driven /> 注解驅動
1、對全部資源放行
在springmvc文件中配置上 <mvc:default-servlet-handler/> ,發出靜態資源請求后,請求傳到 DispatcherServlet,DispatcherServlet 調用 RequestMappingHandlerMapping 進行映射匹配,匹配不成功,DispatcherServlet 最終會將請求轉交給 tomcat 默認 default 進行處理。
<mvc:default-servlet-handler/>
2、對指定目錄下的資源放行 - <mvc:resources/>
如果配置了攔截器,需要在攔截器中進行過濾,否則會被攔截;
* 代表一級目錄,** 代表多級目錄
<mvc:resources location="/css/" mapping="/css/**" /> <mvc:resources location="/js/" mapping="/js/**" /> <mvc:resources location="/fonts/" mapping="/fonts/**" /> <mvc:resources location="/picture/" mapping="/picture/**" /> <mvc:resources location="/admin/" mapping="/admin/**" />
補充說明:多個HandlerMapping的執行順序問題
DefaultAnnotationHandlerMapping 的 order 屬性值是:0 <mvc:resources/ > 自動注冊的 SimpleUrlHandlerMapping的 order 屬性值是: 2147483646 <mvc:default-servlet-handler/> 自動注冊的 SimpleUrlHandlerMapping 的 order 屬性值是: 2147483647
Spring會先執行order值比較小的。
當訪問一個 a.jpg 圖片文件時,先通過 DefaultAnnotationHandlerMapping 來找處理器,一定是找不到的,我們沒有叫 a.jpg 的Action。
再按order值升序找,由於最后一個 SimpleUrlHandlerMapping 是匹 "/**"的,所以一定會匹配上,再響應圖片。
2)在web.xml中放行
1、在 web.xml 配置前端控制器 DispatcherServlet 的時候指定 url-pattern 以擴展名結尾;例如:*.do,*.html 等;
<servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- contextConfigLocation不是必須的, 如果不配置contextConfigLocation, springmvc的配置文件默認找:WEB-INF/servlet的name+"-servlet.xml" --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/springmvc.xml</param-value> </init-param> <!-- 配置springmvc什么時候啟動,參數必須為整數 --> <!-- 如果等於0或大於0,則springmvc隨服務器的啟動而啟動 --> <!-- 小於0,則在第一次訪問的時候啟動 --> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <!-- 1. /* 攔截所有 jsp js png .css 2. *.action *.do 攔截以do action 結尾的請求 3. / 攔截所有 (不包括jsp) (包含.js .png.css) --> <url-pattern>*.do</url-pattern> </servlet-mapping>
2、激活 Tomcat 的 defaultServlet 來處理靜態文件
在 web.xml 配置 default servlet-mapping 的 url-pattern ,以目錄形式和擴展名形式。要寫在DispatcherServlet的前面,讓 defaultServlet 先攔截,這個就不會進入Spring了;
不同的 servlet 容器/應用服務器,處理這些靜態資源的 servlet 的名字不大一樣:
● Tomcat、Jetty、JBoss、and GlassFish 默認 Servlet 的名字 -- "default"
● Google App Engine 默認 Servlet的名字 -- " _ah_default"
● Resin 默認 Servlet的名字 -- "resin-file"
● WebLogic 默認 Servlet的名字 -- " FileServlet"
● WebSphere 默認 Servlet的名字 -- " SimpleFileServlet"
* 代表一級目錄,** 代表多級目錄
<servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/admin/*</url-pattern> <url-pattern>*.css</url-pattern> <url-pattern>*.tff</url-pattern> <url-pattern>*.woff</url-pattern> <url-pattern>*.js</url-pattern> <url-pattern>*.png</url-pattern> </servlet-mapping>
2. 其他請求不到靜態資源的可能原因
1)jsp 或者 html 界面引用 js 文件錯誤
編寫script時沒有寫完整,有些瀏覽器還不報錯。
錯誤:<script type="text/javascript" src="${pageContext.request.contextPath }/css/main.min.css" /> 正確:<script type="text/javascript" src="${pageContext.request.contextPath }/css/main.min.css"></script>
2)在WEB-INF目錄下的靜態資源只有服務器能訪問,客戶端無法直接訪問
眾所周知,WEB-INF 是被保護的目錄,不允許客戶端進行訪問,這里就涉及兩個概念:
請求轉發 和 重定向
請求轉發會間接的由服務器去訪問WEB-INF,所以可以訪問,
重定向請求靜態資源屬於客戶端進行請求,所以不能訪問靜態資源。