默认静态资源管理
在web开发中,静态资源的访问是必不可少的,如:图片、js、css 等资源的访问。spring Boot 对静态资源访问提供了很好的支持,基本使用默认配置就能满足开发需求。
SpringBoot默认为我们提供了静态资源处理,使用WebMvcAutoConfiguration 中的配置各种属性。(注意:如果想自己完全控制webmvc 则可以在自己定义的@Configuration配置类中增加@EnableWebMvc,使默认的WebMvcAutoConfiguration失效)查看WebMvcAutoConfiguration源码:
// Defined as a nested config to ensure WebMvcConfigurer is not read when not
// on the classpath
@Configuration
@Import(EnableWebMvcConfiguration.class)
@EnableConfigurationProperties({ WebMvcProperties.class, ResourceProperties.class })
public static class WebMvcAutoConfigurationAdapter
implements WebMvcConfigurer, ResourceLoaderAware {
private static final Log logger = LogFactory.getLog(WebMvcConfigurer.class);
/**
*静态资源位置定义:CLASSPATH_RESOURCE_LOCATIONS属性定义了默认的位置
* "classpath:/META-INF/resources/",
* "classpath:/resources/",
* "classpath:/static/",
* "classpath:/public/"
**/
//。。。。。。。。。。。省略代码。。。。。。。。。。。。。。。。。
//默认静态资源实现核心代码,如果需要自己处理静态资源可以参考改代码
@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));
}
}
//。。。。。。。。。。。省略代码。。。。。。。。。。。。。。。。。
}
通过代码分析默认配置/**的静态资源映射路径为:
"classpath:/META-INF/resources/",
"classpath:/resources/",
"classpath:/static/",
"classpath:/public/"
通过debug发现最终的映射路径信息如下图所示:
根据以上图片得知,所有的映射路径最终都会加上”/”(注意:在使用配置文件时才会自动加上,或者覆写方法时参考底层实现),最终效果如下:
"classpath:/META-INF/resources/",
"classpath:/resources/",
"classpath:/static/",
"classpath:/public/",
"/"
默认配置的 /webjars/** 映射到 classpath:/META-INF/resources/webjars/
注意:上面的 static、public、resources 等目录都在 classpath: 下面(如 src/main/resources/static)。资源映射的优先级顺序为:META-INF/resources > resources > static > public(可以放入同一个文件进行测试)。如果项目中没有对应的映射路径可以手动创建。
默认映射路径效果图如下:
优先级验证
分别在对应的映射路径中增加文件1.png,然后启动服务访问如下路径查看情况:
http://127.0.0.1:8080/1.png
默认配置文件显示测试,增加index.html文件
在static下面增加文件index.html,内容如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
映射目录测试!<br>
<img alt="映射目录中都存在,但是图片信息不一样" src="http://localhost:8080/1.png"><br>
<img alt="static下" src="http://127.0.0.1:8080/static1.png"><br>
<img alt="resources下" src="resources1.png"><br>
<img alt="public下" src="/public1.png"><br>
<!-- <img alt="META-INF下" src="${rc.contextPath}/meta_inf_resources1.png"><br> -->
<img alt="META-INF下" src="/meta_inf_resources1.png"><br>
</body>
</html>
自定义映射目录
默认情况下,SpringBoot从classpath下的/static(/public,/resources或/META-INF/resources)文件夹,或从ServletContext根目录提供静态内容。这是通过SpringMVC的ResourceHttpRequestHandler实现的,我们可以通过实现接口WebMvcConfigurer(注意在jdk1.8之前的版本中需要继承类WebMvcConfigurerAdapter)并实现addResourceHandlers方法来改变该行为(加载静态文件)或者通过修改配置文件来完成目录的映射。
修改默认映射
在src/main/resources/下创建一个文件夹view,并且创建文件index_view.html,使用以下方式使该文件能够正常访问。访问方式:
http://127.0.0.1:8080/index_view.html
实现接口
package com.sunld;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* 自定义资源映射路径处理类
* @author sunliaodong
*/
@Configuration
public class MyWebMvcConfigurer implements WebMvcConfigurer{
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//将/** 目录下的静态资源映射到classpath:/view/下
registry.addResourceHandler("/**").addResourceLocations("classpath:/view/");
}
}
访问:
http://127.0.0.1:8080/index_view.html
可以正常访问,但是图片信息,获取不到,修改代码如下即可:
package com.sunld;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* 自定义资源映射路径处理类
* @author sunliaodong
*/
@Configuration
//增加该注解之后WebMvcAutoConfiguration中配置就不会生效
//@EnableWebMvc
public class MyWebMvcConfigurer implements WebMvcConfigurer{
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
/**
* 将/** 目录下的静态资源映射到classpath:/view/下
* 直接访问http://127.0.0.1:8080/index_view.html,发现图片信息获取不到需要增加默认的资源映射
* Locations of static resources. Defaults to classpath:[/META-INF/resources/,
* /resources/, /static/, /public/].
*/
//
registry.addResourceHandler("/**").addResourceLocations(
"classpath:/META-INF/resources/",
"classpath:/resources/",
"classpath:/static/",
"classpath:/public/",
"classpath:/view/");
}
}
修改配置文件
首先删除类MyWebMvcConfigurer。
在application.properties下添加如下信息:
#修改默认资源路径映射
# 默认值为 /**
spring.mvc.static-path-pattern=/**
# 默认值为 classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/
# 这里设置要指向的路径,多个使用英文逗号隔开,不影响默认的静态资源映射
spring.resources.static-locations=classpath:/view/
发现配置的view下的页面可以正常访问,以及/META-INF/resources/下的图片可以正常访问,其他默认的静态资源映射路径无法正常访问。按照以下方式修改配置文件即可
#修改默认资源路径映射
# 默认值为 /**
spring.mvc.static-path-pattern=/**
# 默认值为 classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/
# 这里设置要指向的路径,多个使用英文逗号隔开,不影响默认的静态资源映射
spring.resources.static-locations=classpath:/view/,classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/
增加新的映射
把view2/** 映射到classpath:/view/
访问方式:
http://127.0.0.1:8080/view2/index_view2.html
配置中配置了静态模式为/view2/,就只能通过/view2/来访问。
实现接口
package com.sunld;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* 自定义资源映射路径处理类
* @author sunliaodong
*/
@Configuration
//增加该注解之后WebMvcAutoConfiguration中配置就不会生效
//@EnableWebMvc
public class MyWebMvcConfigurer implements WebMvcConfigurer{
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
/**
* 将/** 目录下的静态资源映射到classpath:/view/下
* 直接访问http://127.0.0.1:8080/index_view.html,发现图片信息获取不到需要增加默认的资源映射
* Locations of static resources. Defaults to classpath:[/META-INF/resources/,
* /resources/, /static/, /public/].
*/
registry.addResourceHandler("/**").addResourceLocations(
"classpath:/META-INF/resources/",
"classpath:/resources/",
"classpath:/static/",
"classpath:/public/",
"classpath:/view/");
/**
* 将/view2/** 目录映射到classpath:/view2下
* 这种方式不影响springboot默认的静态资源映射路径,可以注释掉以上代码测试
*/
registry.addResourceHandler("/view2/**").addResourceLocations(
"classpath:/view2/");
}
}
修改配置文件
首先删除类:MyWebMvcConfigurer然后修改配置文件
#增加新的资源路径映射
spring.mvc.static-path-pattern=/view2/**
spring.resources.static-locations=classpath:/view2/
发现默认的静态资源信息访问不到。
总结
修改默认的资源路径映射:
- 修改配置文件,发现配置的view下的页面可以正常访问,以及/META-INF/resources/下的图片可以正常访问,其他默认的静态资源映射路径无法正常访问,可以在配置文件中加上即可。
- 使用接口实现需要加入默认配置文件的映射路径,防止资源信息映射不到(默认的静态资源映射路径被覆盖)
添加新的资源路径映射:
- 通过配置文件的方式会影响默认静态资源映射的访问(被覆盖)
- 不影响默认静态资源的映射访问
总结
参考
Spring Boot干货系列:(六)静态资源和拦截器处理
Spring Boot 系列(四)静态资源处理
Spring Boot 静态资源处理
springboot搭建web(静态资源访问)(三)
Spring Boot - 静态资源处理、启动加载、日志处理
代码
https://github.com/sld880311/springboot-learning/tree/master/springboot_staticresource