SpringBoot —— 静态资源映射规则
SpringBoot —— 静态资源映射规则
SpringBoot
默认为我们提供了静态资源的处理,其通过**自动配置类WebMvcAutoConfiguration
**实现的。此类存放了与web开发相关的各种配置属性和方法。
1 官方文档的描述
默认情况下,SpringBoot
从类路径中的
/static
目录(或/public
或/resources
或/META-INF/resources
)或ServletContext
的根目录中提供静态内容。
它使用SpringMVC
中的ResourceHttpRequestHandler
,
以便您可以通过添加自己的WebMvcConfigurer
并重写addResourceHandlers
方法来修改该行为。
名词解释:
前提,Maven 构建的SpringBoot 工程
-
静态资源:css、js、img、font等
-
类路径:项目下的
/src/main/java
和/src/main/resources
2 静态资源映射规则
2.1 对哪些目录映射?
WebMvcAutoConfiguration
类自动为我们注册了如下目录为静态资源目录,也就是说直接可访问到资源的目录。
优先级从上到下。
所以,如果static里面有个index.html,public下面也有个index.html,则优先会加载static下面的index.html,因为优先级!
classpath:/META-INF/resources/
classpath:/resources/
classpath:/static/
classpath:/public/
/:当前项目的根路径
2.2 目录映射 的理解
就我们在上面五个目录下放静态资源(比如:a.js等),可以直接访问(http://localhost:8080/a.js),类似于以前web项目的webapp下;放到其他目录下无法被访问。
2.3 为什么是这些目录?
2.3.1 看源码
自动配置类WebMvcAutoConfiguration
\org\springframework\boot\autoconfigure\web\servlet\WebMvcAutoConfiguration.class
/**
* 添加 资源处理器 的方法
*
* addResourceHandlers 是 WebMvcAutoConfiguration 实现了接口 WebMvcConfigurer 的方法
*
* @param registry ResourceHandlerRegistry: 资源处理注册器
*
* resourceProperties: 资源 配置类 来封装配置文件的内容
*/
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();
// 以jar包的方式引入静态资源的映射
// 所有 /webjars/** ,都去 classpath:/META-INF/resources/webjars/ 找资源
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));
}
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
// 当前项目的静态资源文件夹映射
// staticPathPattern 是 /** 类路径
// getStaticLocations() 是 "classpath:/META-INF/resources/", "classpath:/resources/", // "classpath:/static/", "classpath:/public/" 类路径下的子路径
this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{staticPathPattern}).addResourceLocations(WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
}
}
资源配置类
\org\springframework\boot\autoconfigure\web\ResourceProperties.class
@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;
public ResourceProperties() {
this.staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
}
// getter
public String[] getStaticLocations() {
return this.staticLocations;
}
// setter
public void setStaticLocations(String[] staticLocations) {
// 每个路径的末尾都追加 " / "
this.staticLocations = this.appendSlashIfNecessary(staticLocations);
}
......
2.3.2 分析的结论
(1)以jar包的方式引入静态资源webjar
所有 /webjars/** ,都去 classpath:/META-INF/resources/webjars/ 找资源
localhost:8080/webjars/jquery/3.5.1/jquery.js
<!‐‐引入jquery‐webjar 在访问的时候只需要写webjars下面资源的名称即可‐‐>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.5.1</version>
</dependency>
(2)"/**" 访问当前项目的任何资源,都去(静态资源的文件夹)找映射
localhost:8080/abc === 去静态资源文件夹里面找abc
"classpath:/META‐INF/resources/",
"classpath:/resources/",
"classpath:/static/",
"classpath:/public/"
"/":当前项目的根路径
3 欢迎页(index.html)映射规则
3.1 官方描述(默认首页)
Spring Boot支持静态和模板欢迎页面。 它首先在配置的静态内容位置中查找index.html文件。
如果未找到,则寻找索引模板。 如果找到任何一个,它将自动用作应用程序的欢迎页面。
就是直接输入127.0.0.1:8080项目名称默认进入的页面
3.2 看源码
自动配置类WebMvcAutoConfiguration
\org\springframework\boot\autoconfigure\web\servlet\WebMvcAutoConfiguration.class
/**
* 往IOC容器中 添加 欢迎页 处理器映射器 组件
*/
@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext, FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, this.getWelcomePage(), this.mvcProperties.getStaticPathPattern());
// 设置 拦截器
welcomePageHandlerMapping.setInterceptors(this.getInterceptors(mvcConversionService, mvcResourceUrlProvider));
// 设置 网络配置
welcomePageHandlerMapping.setCorsConfigurations(this.getCorsConfigurations());
//
return welcomePageHandlerMapping;
}
// 获取 欢迎页
private Optional<Resource> getWelcomePage() {zhaodaodi
String[] locations = WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations());
// 按照优先级,遍历默认静态资源目录后面拼接个index.html的数组
// 比如:[/static/index.html, /public/index.html等等]
// 找到第一个符合条件的 index.html 资源 返回
return Arrays.stream(locations).map(this::getIndexHtml).filter(this::isReadable).findFirst();
}
// 给默认静态资源目录后面拼接个index.html并返回,比如:/static/index.html
private Resource getIndexHtml(String location) {
return this.resourceLoader.getResource(location + "index.html");
}
// 是否可读
private boolean isReadable(Resource resource) {
try {
return resource.exists() && resource.getURL() != null;
} catch (Exception var3) {
return false;
}
}
3.3 分析的结论
WebMvcAutoConfiguration
类自动为我们注册了如下文件为默认首页。
按照优先级找到第一个符合条件的index.html 页面。
优先级从上到下。
所以,如果static里面有个index.html,public下面也有个index.html,则static下面的index.html就是欢迎页。
classpath:/META-INF/resources/index.html
classpath:/resources/index.html
classpath:/static/index.html
classpath:/public/index.html
/index.html
/templates/index.html
4 网站图标(favicon.ico)
favicon.ico即Favorites Icon的缩写,它是一个图标,会出现在支持它的浏览器标题左边。
浏览器会打开网站会自动在网页项目的静态资源路径下,
搜索这个指定文件名的图标文件,有就显示。
故我们的项目其实现在是不需要过多的配置的。
就是这样:
4.1 在2.2.X以上版本的改变
SpringBoot 的提交记录:
提交者wilkinsona,提交时间2019 Aug 21和Aug 23。
稍微读了一下他的操作,第一次把resources路径下的ico文件优先级提高到类路径之前,第二次就直接把默认带的spring网站图标文件favicon.ico文件给删了,即不提供默认的ico文件了,并且把原本在autoconfig里面的配置删了。
不提供默认的ico文件了,并且把原本在autoconfig里面的配置删了
4.2 用法
我们的页面在标签上添加下面一段代码并且资源文件放放对,即可成功让浏览器调到我们的图标文件,如果还没有不妨试试刷新浏览器缓存。
<link rel="icon" href="/img/my_favicon.ico" type="image/x-icon"/>
只要把my_favicon.ico.ico放到如下目录下,就会自动生效。
classpath:/META-INF/resources/
classpath:/resources/
classpath:/static/
classpath:/public/
/:当前项目的根路径