1 静态资源访问问题

我们平时在开发 Web 项目时,不可避免的需要使用到静态资源,例如要用到项目中的图片文件、HTML 文件、CSS 文件、JavaScript 文件等等凡是浏览器直接可以使用且不需要 Tomcat 解析的资源都是静态资源。但是我们在配置 SpringMVC 核心控制器 dispatcherServlet 时,配置的 <url-pattern>/</url-pattern> 表示拦截除 jsp 以外的所有请求,对于前台页面来说想要使用静态资源比如图片、引入 js、css 等,就必须向服务器发送请求才能获取,而此时我们是将 dispatcherServlet 设置为拦截了除 jsp 以外所有请求,所以对于这些静态资源就会获取不到,导致页面出现 404 错误!

充:<url-pattern>/</url-pattern> 表示拦截除 jsp 以外的所有请求。JSP 为什么不拦截呢?因为 tomcat 容器定义了一个名称为 Jsp 的 Servlet,在这里并没有重写

<servlet>
    <servlet-name>jsp</servlet-name>
    <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>jsp</servlet-name>
    <url-pattern>*.jsp</url-pattern>
    <url-pattern>*.jspx</url-pattern>
</servlet-mapping>

2 静态资源访问解决

2.1 使用 <mvc:default-servlet-handler/>

<mvc:default-servlet-handler/> 表示开启默认的 servlet,在 WEB 容器启动的时候会在上下文中定义一个 DefaultServletHttpRequestHandler,它暂时会取代 DispatcherServlet 处理请求的功能,所以这个时候会出现一个新的问题,就是后台 Handler 方法中映射的请求会失效,所以还必须配合 <mvc:annotation-driven /> 使用,设置 <mvc:annotation-driven /> 是将默认 servlet 无法处理的请求交给 DispatcherServlet 处理。

这样配合使用之后,当浏览器输入请求时,如果该请求已经作了映射,那么会接着交给后台对应的处理程序,如果没有作映射,就交给 WEB 应用服务器默认的 Servlet 处理,从而找到对应的静态资源,只有再找不到资源时才会报错。

一般 Web 应用服务器默认的 Servlet 名称是 default,因此 DefaultServletHttpRequestHandler 可以找到它。如果你所有的 Web 应用服务器的默认 Servlet 名称不是 default 或者在缺省 Servlet 名称未知的情况下使用了不同的 Servlet 容器,则需要通过 default-servlet-name 属性显示指定:

<mvc:default-servlet-handler default-servlet-name="xxx" />

当然了,要想使用 <mvc:/> 标签,需要引入 mvc 约束

<beans xmlns:mvc="http://www.springframework.org/schema/mvc"
	   xsi:schemaLocation="
		http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context
		http://www.sprinqframework.orq/schema/context/sprinq-context.xsd
	    http://www.springframework.org/schema/mvc
		http://www.springframework.org/schema/mvc/spring-mvc.xsd">
 
	<!-- 开启默认的servlet -->
	<mvc:default-servlet-handler/>
	<!-- 配置MVC注解驱动 -->
	<mvc:annotation-driven/>
</beans>

2.2 使用 <mvc: resources/>

在 Spring3.0 版本后, Spring 定义了专门用于处理静态资源访问请求的处理器 ResourceHttpRequestHandler 。并且添加了 <mvc: 标签,专门用于解决静态资源无法访问问题。需要在 springmvc 配置文件中添加如下形式的配置

<mvc:resources location="/images/" mapping="/images/**"/>
<!--OR-->
<mvc:resources location="/static/" mapping="/static/**"/>
<!-- 配置MVC注解驱动 -->
<mvc:annotation-driven/>

location 表示静态资源所在目录。当然,目录不要使用 /WEB-INF/ 及其子目录。
mapping 表示对该资源的请求( 以 /images/ 开始的请求,如 /image/beauty.jpg, /images/car.png 等 )。注意,后面是两个星号 **。

通配符含义
**匹配多层路径
*匹配一层路径
?匹配任意单个字符

注意:本地资源路径,必须是 webapp 根目录下的路径

2.3 在 web.xml 中配置 defaultServlet 的 mapping

配置要写在 DispatcherServlet 的前面,让 defaultServlet 先拦截,这个就不会进入 Spring 了

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.js</url-pattern>
    <url-pattern>*.css</url-pattern>
    <url-pattern>*.html</url-pattern>
    <url-pattern>*.htm</url-pattern>
    <url-pattern>*.png</url-pattern>
    <url-pattern>*.jpg</url-pattern>
    <url-pattern>*.gif</url-pattern>
    <url-pattern>*.ico</url-pattern>
</servlet-mapping>