如果在spring-mvc.xml 攔截方式如下配置: <servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 可以自定義servlet.xml配置文件的位置和名稱,默認為WEB-INF目錄下,,名稱為[<servlet-name>]-servlet.xml,,如spring-servlet.xml
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-servlet.xml</param-value> 默認
</init-param>
-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- Spring配置 -->
<listener>
<listenerclass>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<!-- 指定Spring Bean的配置文件所在目錄。默認配置在WEB-INF目錄下 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:config/applicationContext.xml</param-value>
</context-param>
那么,,所有的請求都會被攔截。包括靜態(tài)資源,! '/' 將會替換掉容器的default servlet, 將會處理所有其他handler(Servlet)都不處理的訪問請求.
如果web.xml沒有配置其他特殊路徑的servlet, 基本上所有的請求都交由DispatcherServlet處理.
將不會再訪問容器中原始默認的servlet(你對靜態(tài)資源的訪問就是通過容器默認servlet處理的),,故而靜態(tài)資源將不可訪問!,!
如果想要解決訪問靜態(tài)資源問題,,通常會使用默認handler: <mvc:default-servlet-handler/>
該標簽的xsd文檔說明如下: /*配置一個handler通過轉(zhuǎn)發(fā)到servlet容器的默認servlet來處理靜態(tài)資源*/
Configures a handler for serving static resources by forwarding to the Servlet container's default Servlet.
/*使用該handler允許DispatcherServlet 的url-patter 為'/',同時仍然使用servlet讓其去處理靜態(tài)資源*/
Use of this handler allows using a '/' mapping with the DispatcherServlet while still utilizing the Servlet container to serve static resources.
/*該handler將會轉(zhuǎn)發(fā)所有的請求到默認serlvet*/
This handler will forward all requests to the default Servlet.
/*所以,,在所有的URL HandlerMappings中,,該handler對應(yīng)的mapping應(yīng)該留置最后!*/
Therefore it is important that it remains last in the order of all other URL HandlerMappings.
/*你可以使用兩種方式去保證你的handlermapping 的order屬性值小于DefaultServletHttpRequestHandler 對應(yīng)的handlermapping的order屬性值:使用<mvc:annotation-driven/>標簽或者手動配置HandlerMapping實例并設(shè)置其order屬性值*/
That will be the case if you use the 'annotation-driven' element
or alternatively if you are setting up your customized HandlerMapping instance
be sure to set its 'order' property to a value lower
than that of the DefaultServletHttpRequestHandler, which is Integer.MAX_VALUE.
新的問題出現(xiàn)了,你會發(fā)現(xiàn)以前的Controller不能訪問了?。,。?/p> 那么為什么會出現(xiàn)這個情況,?
DefaultServletHttpRequestHandlerj的avadoc如下: /*使用servlet容器的默認servlet處理靜態(tài)資源*/
* An {@link HttpRequestHandler} for serving static files using the Servlet container's 'default' Servlet.
*
/*當(dāng)DispatcherServlet url-pattern為 ‘/’時,該handler將會使用‘/*’去匹配請求路徑,;因此,,重置了servlet容器對靜態(tài)資源的默認處理*/
* <p>This handler is intended to be used with a '/*' mapping when the
* {@link org.springframework.web.servlet.DispatcherServlet DispatcherServlet}
* is mapped to '/', thus overriding the Servlet container's default handling of static resources.
/*匹配該handler的mapping 應(yīng)該是最后到達,當(dāng)沒有其他mapping可以處理請求時才會執(zhí)行該handler匹配的mapping,。*/
* The mapping to this handler should generally be ordered as the last in the chain so that it will
* only execute when no other more specific mappings (i.e., to controllers) can be matched.
即,,當(dāng)DispatcherServlet url-pattern為 ‘/’時,該handler將會使用‘/*’去匹配請求路徑,。 參考servlet的url-pattern規(guī)則可知 ‘/*’可以攔截一切請求,。因為’/’將servlet定義為默認serlvet,在沒有精確匹配servlet出現(xiàn)前,,’ 這是很嚴重的,, 也就是說,靜態(tài)資源此時可以由默認default servlet進行處理,,但是default servlet不能處理你的業(yè)務(wù)請求(mapping)?。?/p> 所以,,需要保證該handler對應(yīng)的handler mapping在執(zhí)行順序中為最后?。?! 解決辦法: <mvc:annotation-driven />
至于為什么這樣解決,,查看 點擊查看 點擊查看處理靜態(tài)資源的幾種方式springmvc處理靜態(tài)資源的幾種方式 【三種情況下的handlerAdapters:】 其中 AnnotationMethodHandlerAdapter是過期類,,3.2之后被RequestMappingHandlerAdapter替代,。 測試結(jié)果:1 3 可以正常流轉(zhuǎn),2 將找不到對應(yīng)方法,。 【Tips:】DispatcherServlet不攔截jsp請求 前面說的當(dāng)DispatcherServlet配置為’/’, 將會覆蓋default servlet, 將會處理所有其他Servlet都不處理的訪問請求. 所以這里不攔截攔截.jsp, .jspx.的請求, 一定有其他地方攔截了該請求, 但是仔細查找web.xml并沒有發(fā)現(xiàn)其他的servlet,,那一定是在容器中定義的,。 果不其然, 在%TOMCAT_HOME%/conf/web.xml中繼承過來的JspServlet會處理該請求. 該xml配置了兩個servlet: <servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
<init-param>
<param-name>fork</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>xpoweredBy</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
<!-- The mapping for the default servlet -->
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- The mappings for the JSP servlet -->
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.jsp</url-pattern>
<url-pattern>*.jspx</url-pattern>
</servlet-mapping>
這也就是為什么我們直接訪問不在WEB-INF的jsp, 可以直接找到并解析的原因了. |
|