主題:靜態網頁無法訪問
好久沒寫博客了,今天準備寫博客,發現發博客的地方都找不到了,原來改成了創作中心。
進入正題
之前我的網頁是可以正常訪問的,可是當我用上了模板各種CSS和JS文件時,居然無法訪問了。我的思想告訴我,這大概率不是新用的模板網頁的問題,而是,路徑攔截的問題。<後面我也會提一下其他的注意方面是問題>
在web.xml文件中,有這麼一段代碼
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:config/spring/applicationContext-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
注意倒數第二行的url-pattern裏的 /
如果你的DispatcherServlet攔截 *.do這樣的URL,就不存在訪問不到靜態資源的問題。
如果你的DispatcherServlet攔截“/”,攔截了所有的請求,同時對*.js,*.jpg的訪問也就被攔截了。
所以,問題就是爲了可以正常訪問靜態文件,不要找不到靜態文件報404。
有三種方案可供選擇(我用的第一種哦)
方案一:激活Tomcat的defaultServlet來處理靜態文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.png</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>
我在webxml文件中最前面添加了這些代碼,當然要想訪問其他的格式,你可以再額外添加
注意
要寫在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”
方案二:在spring3.0.4以後版本提供了mvc:resources<mvc:resources 的使用方法:
<!–對靜態資源文件的訪問–>
<mvc:resources mapping=”/images/**” location=”/images/” />
/images /**映射到 ResourceHttpRequestHandler 進行處理,location指定靜態資源的位置.可以是web application根目錄下、jar包裏面,這樣可以把靜態資源壓縮到jar包中。cache-period可以使得靜態資源進行web cache
如果出現下面的錯誤,可能是沒有配置 <mvc:annotation-driven /> 的原因。
報錯WARNING: No mapping found for HTTP request with URI [/mvc/user/findUser/lisi/770] in DispatcherServlet with name ‘springMVC’
使用 mvc:resources/ 元素,把 mapping 的 URI 註冊到 SimpleUrlHandlerMapping的urlMap 中,
key 爲 mapping 的 URI pattern值,而 value爲 ResourceHttpRequestHandler,
這樣就巧妙的把對靜態資源的訪問由 HandlerMapping 轉到 ResourceHttpRequestHandler 處理並返回,所以就支持 classpath 目錄, jar 包內靜態資源的訪問.
另外需要注意的一點是,不要對 SimpleUrlHandlerMapping 設置 defaultHandler. 因爲對 static uri 的 defaultHandler 就是ResourceHttpRequestHandler,
否則無法處理static resources request.
方案三:使用mvc:default-servlet-handler/mvc:default-servlet-handler/
會把 “/**” url,註冊到 SimpleUrlHandlerMapping 的 urlMap 中,把對靜態資源的訪問由 HandlerMapping 轉到 org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler 處理並返回.
DefaultServletHttpRequestHandler 使用就是各個 Servlet 容器自己的默認 Servlet.
補充說明:多個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 是匹配 “/**” 的,所以一定會匹配上,再響應圖片。
訪問一個圖片,還要走層層匹配。真不知性能如何?改天做一下壓力測試,與Apache比一比。
重複一下,如果你的 DispatcherServlet 攔截 *.do 這樣的 URL,就不存上述問題了。
其他方案:通過開放tomcat的defaultServlet,修改默認的url-parttern。
但是SpringMVC提供了更爲便捷的方式處理靜態資源。
解決方案:
直接在servlet-context.xml中添加資源映射。
我的開發環境:
1、Eclipse Luna SP1
2、Springsource-tool-suite 3.6.4
修改servlet-context.xml,添加resource映射即可。
servlet-context.xml的路徑如下:
配置文件內容:
複製代碼
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<resources mapping="/images/**" location="/images/" />
<resources mapping="/js/**" location="/js/" />
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<context:component-scan base-package="com.yank.firstapp" />
</beans:beans>
複製代碼
資源映射
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<resources mapping="/images/**" location="/images/" />
<resources mapping="/js/**" location="/js/" />
mapping:映射
location:本地資源路徑,注意必須是webapp根目錄下的路徑。
兩個*,它表示映射resources/下所有的URL,包括子路徑(即接多個/)
這樣我們就可以直接訪問該文件夾下的靜態內容了。
如:
http://localhost:8090/firstapp/images/cookie.png
http://localhost:8090/firstapp/js/jquery-1.11.2.js
注意路徑
配置的location一定要是webapp根目錄下才行,如果你將資源目錄,放置到webapp/WEB-INF下面的話,則就會訪問失敗。這個問題常常會犯。
錯誤方式:
WEB-INF目錄作用
WEB-INF是Java的WEB應用的安全目錄。所謂安全就是客戶端無法訪問,只有服務端可以訪問的目錄。
如果想在頁面中直接訪問其中的文件,必須通過web.xml文件對要訪問的文件進行相應映射才能訪問。
當然,你非要放在WEB-INF中,則必須修改resources映射,如:
<resources mapping="/js/**" location="/WEB-INF/js/" />
如下本文的目錄結構爲如下圖所示。
另外
Spring3中js/css/jpg/gif等靜態資源無法找到(No mapping found for HTTP request with URI)問題解決
最近項目中使用到Spring3,在感嘆Spring3註解配置清爽的同時竟然出現了這個不和諧的事情,實在無法忍受
問題:部署項目後程序加載或用瀏覽器訪問時出現類似的警告,2011-01-19 10:52:51,646 WARN [org.springframework.web.servlet.PageNotFound] -<No mapping found for HTTP request with URI [/sandDemo001/images/1.jpg] in DispatcherServlet with name ‘spring’>,主要看尖括號內部分。
問題原因:罪魁禍首是web.xml下對spring的DispatcherServlet請求url映射的配置,原配置如下:
spring org.springframework.web.servlet.DispatcherServlet 1 spring /分析原因:的/把所有的請求都交給spring去處理了,而所有available的請求url都是在Constroller裏使用類似@RequestMapping(value = “/login/{user}”, method = RequestMethod.GET)這樣的註解配置的,這樣的話對js/css/jpg/gif等靜態資源的訪問就會得不到。
解決方法:在web.xml裏添加如下的配置
default *.css default *.gif default *.jpg default *.js解決方法2:在spring的配置文件中添加如下一行:
注意,需要是spring3.0.5以上版本
解決方法3
<!– Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory –>
<mvc:resources mapping=”/resources/**” location=”/resources/” />
這個配置告訴spring 靜態資源的處理方式。
其他注意方面
jstl的問題,用${pageContext.request.contextPath}這個先繞過jstl的問題。
看看你的攔截器,視圖解析器,路徑輸入是否正確。
images和css、js等文件夾位置是否正確。