场景
静态资源,可以理解为内容固定的页面,包括 HTML、CSS、JS、图片文件等等。浏览器发起请求后服务器根据 URL 查找文件,并将文件内容作为响应,而无需 Java 代码处理业务逻辑,访问效率较高。
前后端分离的今天,Java Web 应用中直接使用静态资源的方式已经很少见了,但不可避免有时候还会用到,例如接口文档 Swagger 就直接将前端代码嵌入了 Java Web 应用中。
Spring MVC 原生支持静态资源,这篇我们主要学习 Spring MVC 静态资源处理的设计思路,以及如何在 Spring MVC 中进行静态资源配置。
Spring MVC 静态资源处理设计思路
普通的 Java Web 项目,代码发布到容器之后,浏览器发起的请求如果没有对应的 Servlet 处理,容器会自动根据 URL 查找项目根目录中的静态资源文件。
对于 Spring MVC 项目而言,通常会配置一个 DispatchServlet 接管所有的请求,这样容器就没有机会自动查找静态资源文件,这意味着静态资源文件也需要 DispatchServlet 进行处理。再看下 DispatchServlet 处理请求的流程图。
DispatchServlet 会将请求交由处理器 Handler 进行处理,那么很自然的,我们为每个表示静态资源文件的 URL 创建一个自定义的处理器就好了。例如:
public class LogoHandler implements HttpRequestHandler { @Override public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { IoUtil.copy(new FileInputStream("/logo.png"), response.getOutputStream()); } }
然后指定处理的路径,我们自定义处理器就可以处理静态资源。例如:
<bean id="/logo.png" class="com.zzuhkp.mvc.LogoHandler"/>
如果静态资源文件比较少使用这种方式还好,如果多的话那么为每个静态资源文件配置一个处理器也太繁琐了,因此我们需要一个能够处理多种静态资源文件的处理器。
Spring 为了简化对静态资源的处理内置了一个处理器 ResourceHttpRequestHandler,因此我们直接将这个处理器配置到容器中即可。
<bean id="/page/*" class="org.springframework.web.servlet.resource.ResourceHttpRequestHandler"> <property name="locationValues" value="classpath:/static/"/> </bean>
当 DispatcherServlet 收到 /page/ 开头的请求,会自动在类路径 /static 中查找资源文件然后进行响应。不过这种配置方式并非官方推荐,下面看官网推荐的配置方式。
Spring MVC 静态资源处理配置
XML 配置
早期的 Spring MVC 使用 XML 配置,使用 XML 配置静态资源处理器的方式如下。
<mvc:resources mapping="/static/**" location="/page/"> </mvc:resources>
是的,就是这么简单。
Java API 配置
在配置类上添加 @EnableWebMvc 注解之后,我们还可以实现 WebMvcConfigurer 接口并重写 addResourceHandlers 方法来配置静态资源处理器,其底层与手动配置静态资源处理器相同。示例代码如下。
@EnableWebMvc @Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/page/*") .addResourceLocations("classpath:/static/"); } }
Spring Boot 静态资源处理配置
Spring Boot 环境下的 Spring MVC 已经默认进行了静态资源处理的配置。默认配置如下:
配置一:
处理的请求路径:/**;
查找的静态资源文件位置:classpath:/META-INF/resources/、classpath:/resources/、classpath:/static/、classpath:/public/,Spring 将优先查找前面的资源文件;
配置二:
处理的请求路径:/webjars/**;
查找的静态资源文件位置:classpath:/META-INF/resources/webjars/;
有了默认配置,我们将静态资源文件放在类路径下 /static 目录即可。
那 webjars 又是怎么回事呢?这是为了避免静态资源文件版本不一致的情况,将多种静态资源文件统一打包到 jar 中的一种方式,打包后的静态资源文件位于类路径 /META-INF/resources/webjars/ 目录中。
如果认为默认的配置不适用,还可以修改 application.properties 文件配置。示例如下。
spring.mvc.static-path-pattern=/page/** spring.resources.add-mappings=true spring.resources.static-locations=classpath:/static/
其中 static-path-pattern
用于配置处理的请求路径,static-locations
用于处理请求路径映射到的静态资源文件路径,如果你想关闭静态资源处理,还可以将 add-mappings
设置为 false
。