静态资源
在 SpringBoot项目中,默认是没有webapp文件夹的
如果你在创建项目时有添加 web的依赖,那它本身就是一个 web项目。
那问题也就接踵而至,没有web文件夹 我们的静态资源应该放哪里呢。
我们将项目结构展开,扫一眼 猜测的话应该是放到这两个文件夹中。
我们先看看放到 static
文件夹中静态资源能否访问
随便编写一个 js文件,并通过浏览器对其进行测试访问
没有问题能够访问到,也就是说我们的静态资源可以放在这个文件夹底下。
我们来了解一下为什么放到这个文件夹底下,虽然很容易猜到是放到这里,但我们要知其所以然。
我们点开 SpringBoot用于存放自动配置类的地方,找到我们的 MVC自动配置类
在其自动配置类中有这么一段代码,这段代码能为我们解惑。
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// 如果对静态资源路径进行了自定义操作,则只有自定义的静态资源路径生效。
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
}
// 还引入了webjars 通过jar包的形式也能够访问静态资源
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));
}
}
自定义路径
自定义路径很好理解,就是通过配置文件的形式 对静态资源加载路径进行自定义操作。
/**
* Locations of static resources. Defaults to classpath:[/META-INF/resources/,
* /resources/, /static/, /public/].
*/
private String[] staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
这是存在于自动配置类中的属性(也就是我们可以配置的配置项)。
我们可以通过的spring.resources.static-locations=
来对静态资源加载路径进行配置,一旦配置后 默认的静态资源加载路径就会失效。SpringBoot会以我们配置的路径为准。(默认的路径下面会说)
一般和spring.mvc.static-Path-Pattern=
配合使用,下面的代码为yaml格式,实际上二者并无太多差别。
spring:
resources:
static-locations: classpath:molu/
mvc:
static-path-pattern: /m/*
我们通过自定义配置,指定静态资源加载的位置为 resources
目录下的molu文件夹。
并对 url进行了一些处理,我们每次访问都需要在前面加上一个 /m才行。
如下图:
关于静态资源的加载位置,我们一般使用默认的就好 自定义显得有些华而不实 如果你没有特定需求的话。
WebJars
我们在开发Java web项目的时候会使用像Maven,Gradle等构建工具以实现对jar包版本依赖管理,以及项目的自动化管理,但是对于JavaScript,Css等前端资源包,我们只能采用拷贝到webapp下的方式,这样做就无法对这些资源进行依赖管理。那么WebJars就提供给我们这些前端资源的jar包形势,我们就可以进行依赖管理。
这个没什么好说的,用的也少 感兴趣可以看看这篇博客
默认路径
关于默认路径有哪些,我们可以通过在配置文件中点进 static-locations
一探究竟
可以看到,默认的静态资源加载位置有四个。也有人说是五个, 但 /** 那个我实在是测不出来,可能是我环境有问题.......
/META-INF/resources/
/resources/
/static/
/public/
/**
(假装有五个)
上面这些静态资源加载位置可以同时存在,且存在优先级 优先级也就是写的顺序。
静态资源的默认访问优先级:/META-INF/resources/
>/resources/
>/static/
>/public/
首页和图标
解决了静态资源位置,我们来看看首页应该如何处理。
SpringBoot创建的项目默认是没有首页的,如果访问 localhost:8080
,会返回一个 error页面。
我们通过阅读源码(mvc 自动配置类),很容易的就能够知道该问题应该如何解决
@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,
FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(
new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(),
this.mvcProperties.getStaticPathPattern());
welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));
welcomePageHandlerMapping.setCorsConfigurations(getCorsConfigurations());
return welcomePageHandlerMapping;
}
private Optional<Resource> getWelcomePage() {
String[] locations = getResourceLocations(this.resourceProperties.getStaticLocations());
return Arrays.stream(locations).map(this::getIndexHtml).filter(this::isReadable).findFirst();
}
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 ex) {
return false;
}
}
大致的意思就是,会在我们的静态资源目录中,找一个文件名为 index.html 的文件来作为首页。
我们测试一下:
确实能够实现,那还有没有其他方式呢?
答案是有的。我们还可以将首页放在 templates
文件夹中,使用 thymeleaf
模板引擎来实现该功能 。
Thymeleaf
Thymeleaf是一个Java / XML / XHTML / HTML5模板引擎 ,可以在Web(基于Servlet)和非Web环境中工作。 它更适合在基于MVC的Web应用程序的视图层提供XHTML / HTML5,但它甚至可以在脱机环境中处理任何XML文件。 它提供完整的Spring Framework。
在Web应用程序中,Thymeleaf旨在成为JavaServerPage(JSP)的完全替代品,并实现自然模板的概念:模板文件可以直接在浏览器中打开,并且仍然可以正确显示为网页。
马上步入2021的现在,jsp已经慢慢淡出人们的视线。而其替代品thymeleaf
,SpringBoot也是比较推荐的。
关于模板引擎的一些概念性的东西我就不写了,网上一搜一箩筐。我们直接讲如何使用(实现首页的跳转)。
在使用之前我们首先导入依赖
- 可以导入对应的starter
- 也可以直接导入相关的两个依赖
导入依赖后,我们了解一下 thymeleaf
能够配置的配置项。
在对SpringBoot自动装配原理了解过后,我们都知道大概率会存在这样一个自动配置类:
该类中的所有属性我们都可以在配置文件中,对其进行自定义配置。
进入该类后,第一眼就能看到以下这些属性
// 编码
private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8;
// 前缀
public static final String DEFAULT_PREFIX = "classpath:/templates/";
// 后缀
public static final String DEFAULT_SUFFIX = ".html";
- 编码应该不需要过多的解释,默认为utf-8,你想改也能改 看个人需求。
- 而前后缀的话,则类似于我们之前配置的视图解析器,要求你将 thymeleaf的页面写在"classpath:/templates/"路径下,且以 .html 结尾。
- 当然,如果你有特定需求 也是可以对其进行修改的。
我们尝试实现一下
在 templates 文件夹中编写一个测试用的html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>thymeleaf Test</h1>
</body>
</html>
编写视图跳转所需要的Controller类
@Controller
public class HelloController {
@RequestMapping("/test")
public String test(){
return "test!";
}
}
启动项目,在浏览器中输入 localhost:8080/test:
没有任何问题,最简单的使用还是很容易就能做到。
那我们要使用 thymeleaf
来做到首页的跳转,大致也就有了思路。
- 将
index.html
写在templates
文件夹下 - 编写
Controller
类
@Controller
public class HelloController {
@RequestMapping("/")
public String test(){
return "index";
}
}
访问测试:
没有任何问题.
关于 thymeleaf实际上能讲的东西非常之多,这里只简单涉及 之后有时间会另开一篇博客来讲讲 thymeleaf
图标
我们还可以在静态资源加载位置放一张图片来作为我们的网页图标
- 我们将需要设置为图标的图片文件重命名为
favicon.ico
- 将重命名好的图片文件移动至我们静态资源加载的位置
图片没有损坏能够正常打开就没有问题
我们重启项目,再次访问
这个时候我们的网页就存在图标了。
好像2.20版本之前,还需要在配置文件中配置才能生效。
如果不确定你的版本是否能直接生效,你可以在配置文件中 输入spring.mvc.favicon.enabled,如果没有该配置项应该是能够直接生效的。反之则需要配置为false
放松一下眼睛
夹带私货(不是