8.1 原理分析
springboot中,没有web.xml,但是我们需要访问相应的静态资源(html,css,js等)
现在的问题是,咱们的静态资源应该放在哪里? 我们分析一波源码!
-
思考:既然是静态资源,肯定是分析mvc的配置与源码!所有MVC相关的配置(视图解析器,上传下载,静态资源等)都在
WebMvcAutoConfiguration
这个类中 -
addResourceHandlers
:静态资源处理方法解析
@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();
//第二种方案 判断是存在一个 /webjars/** 的映射路径
if (!registry.hasMappingForPattern("/webjars/**")) {
customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/")
.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
//第三种方案:获取静态资源路径
/**
从代码中可以找到相关的资源资源路径 staticPathPattern == /**
this.resourceProperties.getStaticLocations() -> CLASSPATH_RESOURCE_LOCATIONS ->
"classpath:/META-INF/resources/",
"classpath:/resources/", "classpath:/static/", "classpath:/public/"
结论:咱们可以上述三个路径中找到静态文件
*/
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
.addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
}
8.2 自己静态资源-静态资源路径
从源码是我们分析中四个路径(正好也是访问优先级)
1. `classpath:/META-INF/resources/`
2. `classpath:/resources/`
3. `classpath:/static/`
4. `classpath:/public/`
优先级分析:大家可以在四个路径中新建四个相同的资源文件测试
8.3 三方静态资源 webjars
8.3.1. webjar 认识
WebJars是将客户端(浏览器)资源(JavaScript,Css等)打成jar包文件,以对资源进行统一依赖管理。WebJars的jar包部署在Maven中央仓库上。
8.3.2 引入webjars代码:
- webjars 引入网页路径 : https://www.webjars.org/
<!--webjars-locator 包的作用是省略 webjar 的版本。
比如对于请求 http://localhost:8080/webjars/jquery/3.8.1/jquery.js省略版本号 3.8.1
直接使用http://localhost:8080/webjars/jquery/jquery.js也可访问。-->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator</artifactId>
<version>0.32-1</version>
</dependency>
<!--引入bootstrap-->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.7-1</version>
</dependency>
<!--引入jQuery-->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.8.1</version>
</dependency>
8.3.3. 引入jquery的路径
8.3.4. 效果测试
8.4 主页&图标处理
8.4.1 源码分析
通过源码可以分析得知 : springboot会默认云找静态资源中的index.html页面
//很明显是欢迎页处理映射器
@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,
FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
//创建相应的处理映射器(主要分析方法)
/**
调用 getWelcomePage()方法
this.mvcProperties.getStaticPathPattern() 拿到静态资源路径
*/
WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(
new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(),
this.mvcProperties.getStaticPathPattern());
//设置相应的拦截器
welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));
return welcomePageHandlerMapping;
}
//拿到所有资源配置的路径
private Optional<Resource> getWelcomePage() {
String[] locations = getResourceLocations(this.resourceProperties.getStaticLocations());
return Arrays.stream(locations).map(this::getIndexHtml).filter(this::isReadable).findFirst();
}
//拿到路径中的index.html页面
private Resource getIndexHtml(String location) {
return this.resourceLoader.getResource(location + "index.html");
}
8.4.2 主页
任意静态资源路径放入index.html就OK
8.4.3 图标处理
springboot中的图标名称:
favicon.ico
- 注:springboot之前的版本需要开始图片修改
public enum StaticResourceLocation {
CSS(new String[]{"/css/**"}),
JAVA_SCRIPT(new String[]{"/js/**"}),
IMAGES(new String[]{"/images/**"}),
WEB_JARS(new String[]{"/webjars/**"}),
FAVICON(new String[]{"/**/favicon.ico"});
private final String[] patterns;
private StaticResourceLocation(String... patterns) {
this.patterns = patterns;
}
public Stream<String> getPatterns() {
return Arrays.stream(this.patterns);
}
}
进行图标修改:在静态资源的位置加上
favicon.ico
图标即可
8.5 小结
本章节我们学习了如何在springboot使用自己的静态资源,三方静态资料,默认主页,favicon图标处理。