Skip to content

SpringMVC教程 - 10 静态资源处理

在 SpringMVC + Thymeleaf 的传统Web应用中,除了动态生成的页面内容外,我们还需要处理大量的静态资源,比如图片、CSS文件、JavaScript文件等。这些资源不需要服务器进行动态处理,可以直接返回给浏览器。

但是现在默认所有的请求都会寻找对应的 Controller 处理,所以就需要额外的配置。

10.1 webapp文件夹

在一个标准的 传统 SpringMVC 项目 中,结构如下:

src/
 └─ main/
     ├─ java/                 → Java 源代码
     ├─ resources/            → 资源文件(配置、Spring XML 等)
     └─ webapp/               → Web 应用根目录(相当于部署时的 web 根目录)
         ├─ WEB-INF/          → 特殊目录(受保护)

当项目打包成 .war 部署到 Tomcat(或其他 Servlet 容器)时, webapp 的内容会直接映射为网站的根目录,在 webapp 目录下WEB-INF 外的所有文件都是可以通过浏览器直接访问的,所以静态资源一般都是放在 webapp 目录下的。

WEB-INF 是 Servlet 规范定义的一个特殊目录,外部浏览器无法直接访问其中的内容,避免暴露内部逻辑,只能通过 服务器端的请求转发(forward)控制器返回视图 来访问。

但是在配置项目的时候,我们配置了 SpringMVC 的前端处理器 DispatcherServlet 拦截了所以的请求,这意味着如果我们不做特殊配置,当浏览器请求静态资源(如CSS、JS、图片文件)时,这些请求也会被DispatcherServlet拦截,所以会导致静态资源无法正常访问。

10.2 静态资源配置

下面就来介绍一下如何配置。

首先我们一般会在 webapp 目录下新建 static 文件夹,然后在其下新建 css、js、img 等文件夹,放置不同的静态资源。

例如我新建了 webapp/static/js ,并在其下创建 index.js,内容如下:

js
function sayHello() {
    alert('Hello For技术栈');
}
  • 简单定义一个函数,后面在页面中引入这个 js 文件。

下面来配置 SpringMVC,让静态资源可以正常被访问。


1 方式一

我们需要在 SpringMVC 配置文件中添加如下配置:

xml
<!-- 一定要配置这个才可以,可能之前已经配置了 -->
<mvc:annotation-driven />

<!-- 静态资源映射 -->
<mvc:resources mapping="/static/**" location="/static/" />
  • 这样当请求路径以 /static/ 开头时,不要交给 Controller,而是直接去找 /static/ 目录下的真实文件。

所以运行项目后,请求项目下的静态文件:

http://localhost:8080/static/js/index.js

会被映射到:

webapp/static/js/index.js

此时通过浏览器是可以直接访问到 index.js 文件的。


而在 Thymeleaf 模板文件中,可以通过如下方式引入静态文件即可:

html
<!-- 引入js -->
<script th:src="@{/static/js/index.js}"></script>

<!-- 引入css -->
<link rel="stylesheet" th:href="@{/static/css/index.css}">

<!-- 引入图片 -->
<img th:src="@{/static/img/logo.png}" />

2 方式二

在 SpringMVC 配置文件中添加如下配置:

xml
<!-- 一定要配置这个才可以,可能之前已经配置了 -->
<mvc:annotation-driven />

<!-- 静态资源映射 -->
<mvc:default-servlet-handler />
  • 作用是当 SpringMVC 找不到对应的控制器映射时,把请求交还给 容器(Tomcat)默认的 Servlet(DefaultServlet) 处理。

如果你打开 Tomcat 目录下的 conf/web.xml 可以看到其中有如下代码:

xml
<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,当 SpringMVC 把请求交回给它后,它就会直接返回对应的静态资源。

上面两种方式都可以。