avatar

SpringBoot的静态资源访问方案

摘要:本文介绍了Springboot的静态资源访问方案,包括设置静态资源路径以及自定义静态资源目录等

SpringBoot默认的静态资源访问方案


当我们使用 SpringMVC 框架时,静态资源会被拦截,需要添加额外配置。要讲 Spring Boot 中的问题,我们得先回到 SSM 环境搭建中,一般来说,我们可以通过 <mvc:resources /> 节点来配置不拦截静态资源

1
<mvc:resources mapping="/**" location="/"/>

/**表示可以匹配任意层级的路径,以上配置是在XML中的配置,若在Java代码中进行配置,则需要自定义一个类,并继承自WebMvcConfigurationSupport,然后实现addResourceHandlers方法即可

1
2
3
4
5
6
7
8
@Configuration
@ComponentScan(basePackages = "org.sang.javassm")
public class SpringMVCConfig extends WebMvcConfigurationSupport {
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations("/");
}
}

那么在SpringBoot中是如何实现自动配置的呢?我们来看WebMvcAutoConfiguration类里面的addResourceHandlers方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
}
Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
if (!registry.hasMappingForPattern("/webjars/**")) {
customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/")
.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
.addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
}

通过ctrl+左键点击,我们可以查看staticPathPattern的值其实是/**,并通过addResourceHandler方法加载到配置中去。

1
2
3
4
/**
* Path pattern used for static resources.
*/
private String staticPathPattern = "/**";

然后我们再来看getStaticLocations()中的返回值是什么,一路查找下去我们发现其返回值是一个数组,定义了静态资源的访问路径,并且具有优先级。然后通过addResourceLocations方法加载到配置中去。

1
2
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
"classpath:/resources/", "classpath:/static/", "classpath:/public/" };
  • classpath:/META-INF/resources/

  • classpath:/resources/

  • classpath:/static/

  • classpath:/public/

  • /

前四个目录好理解,分别对应了resources目录下不同的目录,第5个 / 是啥意思呢?我们知道,在 Spring Boot 项目中,默认是没有 webapp 这个目录的,当然我们也可以自己添加(例如在需要使用JSP的时候),这里第5个 / 其实就是表示 webapp 目录中的静态资源也不被拦截。如果同一个文件分别出现在五个目录下,那么优先级也是按照上面列出的顺序。

自定义静态资源位置


那么如果我们想自定义静态资源的位置呢?我们可以通过application.properties或Java代码来自定义。

application.properties

1
2
spring.resources.static-locations=classpath:/myStatic
spring.mvc.static-path-pattern=/**

Java代码

1
2
3
4
5
6
7
@Configuration
public class WebMVCConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations("classpath:/myStatic/");
}
}
Author: WJZheng
Link: https://wellenzheng.github.io/2020/03/15/SpringBoot%E7%9A%84%E9%9D%99%E6%80%81%E8%B5%84%E6%BA%90%E8%AE%BF%E9%97%AE%E6%96%B9%E6%A1%88/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.

Comment