我们来了解下 SpringBoot 是如何对静态资源进行处理的吧。
【开发环境】:
SpringBoot 默认为我们提供了静态资源的处理,其通过配置类 WebMvcAutoConfiguration
实现的。此类存放了与 web 开发相关的各种配置属性和方法。
查看 WebMvcAutoConfiguration
类的源码。在此类中,addResourceHandlers()
方法对静态资源路径作出了默认的处理
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
} else {
Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
if (!registry.hasMappingForPattern("/webjars/**")) {
this
.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{"/webjars/**"})
.addResourceLocations(new String[]{"classpath:/META-INF/resources/webjars/"})
.setCachePeriod(this.getSeconds(cachePeriod))
.setCacheControl(cacheControl));
}
// 在此处做静态资源路径映射
// staticPathPattern 的值为“/**”,下面会做出解释
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
this
.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{staticPathPattern})
// this.resourceProperties.getStaticLocations()可以得出静态资源路径
.addResourceLocations(WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations()))
.setCachePeriod(this.getSeconds(cachePeriod))
.setCacheControl(cacheControl));
}
}
}
解释:
staticPathPattern 的值为什么是:/**
this.mvcProperties
是 WebMvcProperties 类型,作为了 WebMvcAutoConfiguration 类的属性。查看WebMvcProperties 类,在其构造方法中,有对 staticPathPattern
属性进行初始化,其值为:
public class WebMvcProperties {
//...
private String staticPathPattern;
public WebMvcProperties() {
this.localeResolver = WebMvcProperties.LocaleResolver.ACCEPT_HEADER;
this.dispatchTraceRequest = false;
this.dispatchOptionsRequest = true;
this.ignoreDefaultModelOnRedirect = true;
this.throwExceptionIfNoHandlerFound = false;
this.logResolvedException = false;
this.staticPathPattern = "/**";
this.async = new WebMvcProperties.Async();
this.servlet = new WebMvcProperties.Servlet();
this.view = new WebMvcProperties.View();
this.contentnegotiation = new WebMvcProperties.Contentnegotiation();
this.pathmatch = new WebMvcProperties.Pathmatch();
}
}
this.resourceProperties.getStaticLocations() 得出的静态资源路径是什么?
this.resourceProperties
是 ResourceProperties 类型。查看其源码:
@ConfigurationProperties(
prefix = "spring.resources",
ignoreUnknownFields = false
)
public class ResourceProperties {
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{"classpath:/META-INF/resources/", "classpath:/resources/",
"classpath:/static/", "classpath:/public/"};
private String[] staticLocations;
private boolean addMappings;
private final ResourceProperties.Chain chain;
private final ResourceProperties.Cache cache;
public ResourceProperties() {
this.staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
this.addMappings = true;
this.chain = new ResourceProperties.Chain();
this.cache = new ResourceProperties.Cache();
}
public String[] getStaticLocations() {
return this.staticLocations;
}
...
}
在其构造方法中,将上述四个类路径赋值给了属性 staticLocations
。
从 addResourceHandlers()
方法中,可以看出两点关键信息:
1、 访问路径的形式是:/webjars/**
,则去 classpath:/META-INF/resources/webjars/
路径下查找静态资源。
1)、什么是webjars?以jar包的形式引入静态资源文件
2)、webjars的官网
2、访问路径的形式是:/**
,则去 classpath:/META-INF/resources/"、"classpath:/resources/"、"classpath:/static/"、"classpath:/public/
路径下查找静态资源
例如:访问 static
文件夹下的一张图片
访问路径:http://localhost:8080/1.jpg
。千万不要带上static路径,否则,会访问不到
好了,到此,以上都是 SpringBoot 默认为我们提供的静态资源路径映射处理。
问题:
如果我在 resources 路径下新建一个文件 mystatic,然后将 1.jpg 放入其中,那我能访问吗?
http://localhost:8080/1.jpg
、http://localhost:8080/mystatic/1.jpg
发现这两个路径访问都是报 404。即:SpringBoot 的默认配置已经不支持了,这时候,需要我们自定义一些配置了。
创建一个Java类并实现接口 WebMvcConfigurer
,重写 addResourceHandlers()
方法
@Configuration
public class MyStaticConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// 访问路径以 “/mystatic” 开头时,会去 “mystatic” 路径下找静态资源
registry
.addResourceHandler("/mystatic/**")
.addResourceLocations("classpath:/mystatic/");
}
}
在 main/resources
下新建 mystatic
文件夹,并放入一张图片 1.jpg
。
访问:http://localhost:8080/mystatic/1.jpg
如果我们将 /mystatic/**
修改为 /**
,这时,就是 SpringBoot 默认配置相同,则会覆盖系统的默认配置。可以多次调用 addResourceLocations()
添加目录,优先级先添加的高于后添加的。
【注意】:这样使用代码的方式自定义目录映射,并不影响SpringBoot 的默认映射,可以同时使用。
addResourceLocations("classpath:/mystatic/")
可以指定任何位置:
classpath:
file:
。如:file:/E:/upload/
spring:
mvc:
static-path-pattern: /run/**
再访问静态资源时,需要以“run”开头。如:访问 static/1.jpg
文件。
访问:http:localhost:8080/run/1.jpg
# 配置静态资源访问前缀 默认为“/**”
spring.mvc.static-path-pattern=/test/**
# 配置静态资源路径,默认配置失效。默认值为 classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/
spring.resources.static-locations=classpath:/mystatic
此种配置会覆盖默认配置,只能以 test
开头来访问 mystatic
文件夹下的静态资源
访问:http://localhost:8080/test/1.jpg
两种方式访问html页面:
直接通过路径访问页面,这种方式跟上面访问图片一样,就不再说了。下面就简要说一下通过控制器地址跳转到 HTML 页面
步骤一》、先写一个静态页面:在 resources/pages
下新建一个 HTML 页面 hello.html
:
步骤二》、写一个控制器 TestController
@Controller
@RequestMapping("/test")
public class TestController {
@GetMapping("/hello")
public String hello() {
return "hello";
}
}
步骤三》、配置文件中添加配置
spring:
mvc:
view:
prefix: /pages/ # 前缀 => 页面的位置 /static/pages
suffix: .html # 后缀 => 文件的后缀 hello.html
步骤四》、访问
http://localhost:8080/pages/hello.html
===========================================================================================
2023-05-29 更:
映射本地文件,可供前端访问
如:在一个 SpringBoot 工程中如何访问一个 D 盘下的一个图片:D:/zzc/pic/1.jpg
使用配置:
spring:
mvc:
# 资源访问的前缀
static-path-pattern: /staFile/**
# 扫描的资源路径
resources:
static-locations: classpath:/resources/,classpath:/static/,file:${file.dir}
file:
dir: D:/zzc/pic/
启动,访问:
http://localhost:8092/staFile/1.jpg
使用代码:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Value("${file.dir}")
private String fileDir;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// 访问路径以 “/staFile” 开头时,会去 磁盘 fileDir 路径下找静态资源
registry
.addResourceHandler("/staFile/**")
.addResourceLocations("file:" + fileDir);
}
}
Spring Boot 2.6+后映射匹配的默认策略已从AntPathMatcher更改为PathPatternParser,需要手动指定为ant-path-matcher
修改 yml 配置
spring:
mvc:
pathmatch:
matching-strategy: ant_path_matcher
配置静态资源路径static-locations、static-path-pattern
【参考资料】:
第4篇:spring boot对静态资源的管理
Spring Boot 静态资源处理
Spring Boot静态资源访问和配置全解析(看不懂你打我)