原因
在我們配置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
頁面時,沒有被攔截的原因。
解決方案
-
爲
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/>