關於SpringMVC下,無法使用靜態資源的問題及解決

原因

在我們配置SpringMVC的時候,在web.xml中配置過一個DispatcherServlet,代碼如下

	<!--配置springmvc DispatcherServlet,前端控制器-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/springmvc-config.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <!-- 攔截器配置,攔截所有請求 -->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

我們在url-pattern攔截了所有的請求(除了jsp),然後SpringMVC就會在容器中尋找對應的處理器去處理這個請求,這也就導致瞭如果請求的是靜態資源(圖片,js等),那麼就會無法訪問成功。

順帶一提,關於爲什麼沒有攔截掉jsp頁面請求的原因

因爲在tomcat的配置文件web.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>
<!-- The mapping for the default servlet -->
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
	
	<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 mappings for the JSP servlet -->
    <servlet-mapping>
        <servlet-name>jsp</servlet-name>
	        <url-pattern>*.jsp</url-pattern>
        <url-pattern>*.jspx</url-pattern>
    </servlet-mapping>

然後如果我們配置了DispatcherServlet,就會覆蓋掉默認的DefaultServlet,導致靜態資源解析失敗,但是如果傳過來的是jsp文件,因爲一個優先級的原因,如圖在這裏插入圖片描述

所以tomcat配置的JspServlet會優先DispatcherServlet執行,也就解釋了爲什麼當請求jsp頁面時,沒有被攔截的原因。

解決方案

  1. spring的配置文件中配置

     <mvc:default-servlet-handler/>
    

    加上這行代碼,SpringMVC在運行的時候,會有在這裏插入圖片描述

使用SimpleUrlHandlerMapping來處理這個映射關係,映射關係如如下在這裏插入圖片描述
我們可以看到,這個map可以攔截所有的請求,用DefaultServletHttpRequestHandler來處理,然後這個handler實際上就會使用tomcat默認的servlet來處理,這樣就能夠加載靜態資源了。

當然這還沒有結束,如果只是單純的加這一行代碼,結果就是雖然能夠訪問靜態資源了,但是所有用註解@RequestMapping()全都失效了。

原因也很簡單,缺少了一個關於註解的mapping,因爲下圖的這兩個,都不能夠解析註解
在這裏插入圖片描述
所以,只需要再手動配置了一個關於註解的Mapping即可。

這裏有兩種方式

	<!-- 1. 配置RequestMappingHandlerMapping -->
    <!-- 配置annotation類型的處理映射器,它根據請求查找映射 -->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
    </bean>
    <!-- 配置annotation類型的處理器適配器,完成對@RequestMapping標註方法的調用 -->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
    <!-- 配置視圖解析器 -->

又或者是直接配置註解驅動

  <mvc:annotation-driven/>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章