SpringMVC - 導致 Controller失效

如果在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>&nbsp; 默認
    </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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

那麼,所有的請求都會被攔截。包括靜態資源!

如果想要解決訪問靜態資源問題,通常會使用默認handler:

<mvc:default-servlet-handler/>
  • 1
  • 1

新的問題出現了,你會發現以前的Controller不能訪問了!!!

解決辦法:

<mvc:annotation-driven />
  • 1
  • 1

點擊查看 <mvc:annotation-driven />詳解annotation-driven詳解


【Tips:】

default-servlet-handler將在SpringMVC上下文中定義一個DefaultServletHttpRequestHandler,它會對進入DispatcherServlet的請求進行篩查。

如果發現是沒有經過映射的請求,就將該請求交由WEB應用服務器默認的Servlet進行處理。如果不是靜態資源的請求,才由DispatcherServlet繼續進行處理。


【三種情況下的handlerAdapters:】

這裏寫圖片描述 
這裏寫圖片描述

其中 AnnotationMethodHandlerAdapter是過期類,3.2之後被RequestMappingHandlerAdapter替代。

測試結果:1 3 可以正常流轉,2 將找不到對應方法。




-----------------------------------------------------------------------------------------------

優雅REST風格的資源URL不希望帶 .html 或 .do 等後綴.由於早期的Spring MVC不能很好地處理靜態資源,所以在web.xml中配置DispatcherServlet的請求映射,往往使用 *.do 、 *.xhtml等方式。這就決定了請求URL必須是一個帶後綴的URL,而無法採用真正的REST風格的URL。 


如果將DispatcherServlet請求映射配置爲"/",則Spring MVC將捕獲Web容器所有的請求,包括靜態資源的請求,Spring MVC會將它們當成一個普通請求處理,因此找不到對應處理器將導致錯誤。 

如何讓Spring框架能夠捕獲所有URL的請求,同時又將靜態資源的請求轉由Web容器處理,是可將DispatcherServlet的請求映射配置爲"/"的前提。由於REST是Spring3.0最重要的功能之一,所以Spring團隊很看重靜態資源處理這項任務,給出了堪稱經典的兩種解決方案。 

先調整web.xml中的DispatcherServlet的配置,使其可以捕獲所有的請求: 

Java代碼  收藏代碼
  1. <servlet>  
  2.         <servlet-name>springMVC</servlet-name>  
  3.         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
  4.         <load-on-startup>1</load-on-startup>  
  5.     </servlet>  
  6.     <servlet-mapping>  
  7.         <servlet-name>springMVC</servlet-name>  
  8.         <url-pattern>/</url-pattern>  
  9.     </servlet-mapping>  

通過上面url-pattern的配置,所有URL請求都將被Spring MVC的DispatcherServlet截獲。 

採用<mvc:default-servlet-handler /> 

在springMVC-servlet.xml中配置<mvc:default-servlet-handler />後,會在Spring MVC上下文中定義一個org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler,它會像一個檢查員,對進入DispatcherServlet的URL進行篩查,如果發現是靜態資源的請求,就將該請求轉由Web應用服務器默認的Servlet處理,如果不是靜態資源的請求,才由DispatcherServlet繼續處理。 

一般Web應用服務器默認的Servlet名稱是"default",因此DefaultServletHttpRequestHandler可以找到它。如果你所有的Web應用服務器的默認Servlet名稱不是"default",則需要通過default-servlet-name屬性顯示指定: 

<mvc:default-servlet-handler default-servlet-name="所使用的Web服務器默認使用的Servlet名稱" /> 

採用<mvc:resources /> 

<mvc:default-servlet-handler />將靜態資源的處理經由Spring MVC框架交回Web應用服務器處理。而<mvc:resources />更進一步,由Spring MVC框架自己處理靜態資源,並添加一些有用的附加值功能。 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章