SpringBoot学习篇|静态资源&模板の加载
预备
开局先写一个helloworld的控制器
package com.example.demo.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class Hello {
@RequestMapping("/hello")
String hello(){
return "Hello World!!!";
}
}
项目初始结构如下:
简单的了解
静态资源的加载我们可以看到org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter#addResourceHandlers函数
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
} else {
this.addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
registration.addResourceLocations(this.resourceProperties.getStaticLocations());
if (this.servletContext != null) {
ServletContextResource resource = new ServletContextResource(this.servletContext, "/");
registration.addResourceLocations(new Resource[]{resource});
}
});
}
}
-
如果我们对this.resourceProperties记性了修改的话就会满足if条件,按照我们的规则进行资源加载,不然的话就按照默认配置走else
-
如果路径匹配
/webjars/**
那就加载classpath:/META-INF/resources/webjars/
的资源 -
然后匹配
this.mvcProperties.getStaticPathPattern()
(其实就是\**
)的路径那就添加资源路径this.resourceProperties.getStaticLocations()
之后在资源路径中进行资源查询this.resourceProperties.getStaticLocations():
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{ "classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/" };
-
在
this.resourceProperties.getStaticLocations()
路径中找到资源后通过servletContext
返回资源
资源的加载也是有优先级的,例如在有classpath:/static/
和classpath:/public/
下面都有1.js,如果我们直接访问/1.js
最后访问到的是classpath:/static/
下的1.js
四个目录的优先级依次降低(优先访问到级别高的):
classpath:/META-INF/resources/
classpath:/resources/
classpath:/static/
classpath:/public/
/webjars/xxx
当我们访问/webjars/**
形式的目录时,Springboot就会在classpath:/META-INF/resources/webjars/
目录下寻找对应的请求资源
而classpath:/META-INF/resources/webjars/
是webjars类型的依赖jar包专有的格式,可以通过导入包在这下面找到很多的js文件,maven依赖可以从其官网复制到pom.xml即可
这里安装一个AjaxQ的webjars依赖
<dependency>
<groupId>org.webjars</groupId>
<artifactId>AjaxQ</artifactId>
<version>0.0.2</version>
</dependency>
可以看到webjars的jar包里面js文件所在路径是满足路径格式的,我们打开浏览器访问webjars中的js:
/xxx
默认只要资源放在以下目录中均可直接访问到对应的静态资源
classpath:/META-INF/resources/
classpath:/resources/
classpath:/static/
classpath:/public/
首页配置
欢迎页的处理映射函数org.springframework.boot.autoconfigure.web.servlet.WelcomePageHandlerMapping
@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;
}
this.mvcProperties.getStaticPathPattern()
获得自定义的处理映射,也可以通过this.getWelcomePage()
获取默认首页
private Resource getWelcomePage() {
String[] var1 = this.resourceProperties.getStaticLocations();
int var2 = var1.length;
for(int var3 = 0; var3 < var2; ++var3) {
String location = var1[var3];
Resource indexHtml = this.getIndexHtml(location);
if (indexHtml != null) {
return indexHtml;
}
}
ServletContext servletContext = this.getServletContext();
if (servletContext != null) {
return this.getIndexHtml((Resource)(new ServletContextResource(servletContext, "/")));
} else {
return null;
}
}
private Resource getIndexHtml(String location) {
return this.getIndexHtml(this.resourceLoader.getResource(location));
}
private Resource getIndexHtml(Resource location) {
try {
Resource resource = location.createRelative("index.html");
if (resource.exists() && resource.getURL() != null) {
return resource;
}
} catch (Exception var3) {
}
return null;
}
默认最后加载的是上面四个静态页面下的index.html
切换图标
在老版本的Springboot中可以在静态资源目录下放入一个favicon.ico
图标,然后在application.properties
中设置spring.mvc.favicon.enables=false
关闭默认图标
然后网站图标就会变为我们放入的favicon.ico
图标
模板引擎
jsp也是一种模板引擎的渲染显示方式,对应的是.jsp文件,而这里的Thymeleaf
模板引擎就是直接在.html
页面中使用Thymeleaf
语法,进行模板渲染
在这选择使用Thymeleaf
,需要我们另外导入包才能使用,但是在Springboot中已经包含这个依赖,我们只要导入场景即可
Thymeleaf 模板引擎支持多种表达式:
- 变量表达式:${…}
- 选择变量表达式:*{…}
- 链接表达式:@{…}
- 国际化表达式:#{…}
- 片段引用表达式:~{…}
使用变量表达式还可以使用内置基本对象,获取内置对象的属性,调用内置对象的方法。 Thymeleaf 中常用的内置基本对象如下:
- ctx :上下文对象;
- vars :上下文变量;
- locale:上下文的语言环境;
- request:HttpServletRequest 对象(仅在 Web 应用中可用);
- response:HttpServletResponse 对象(仅在 Web 应用中可用);
- session:HttpSession 对象(仅在 Web 应用中可用);
- servletContext:ServletContext 对象(仅在 Web 应用中可用)。
除了能使用内置的基本对象外,变量表达式还可以使用一些内置的工具对象。
- strings:字符串工具对象,常用方法有:equals、equalsIgnoreCase、length、trim、toUpperCase、toLowerCase、indexOf、substring、replace、startsWith、endsWith,contains 和 containsIgnoreCase 等;
- numbers:数字工具对象,常用的方法有:formatDecimal 等;
- bools:布尔工具对象,常用的方法有:isTrue 和 isFalse 等;
- arrays:数组工具对象,常用的方法有:toArray、length、isEmpty、contains 和 containsAll 等;
- lists/sets:List/Set 集合工具对象,常用的方法有:toList、size、isEmpty、contains、containsAll 和 sort 等;
- maps:Map 集合工具对象,常用的方法有:size、isEmpty、containsKey 和 containsValue 等;
- dates:日期工具对象,常用的方法有:format、year、month、hour 和 createNow 等。
除了上面的一些用法之外还有很多的一些属性和语法,在这里不一一介绍,更多的用法还是得看官网,这里简单说一下怎么进行变量传递读取
index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Index Page</title>
</head>
<body>
<div th:text="{name}"></div>
<div th:utext="{name}"></div>
<h2>遍历效果</h2>
<h3 th:each="user:{users}" th:text="{user}"></h3>
<h3 th:each="user:{users}">[[{user} ]]</h3>
</body>
</html>
想要传入msg
变量的话可以为控制器添加以下代码
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class Index {
@RequestMapping("/index")
public String index(Moudle moudle){
moudle.addAttribute("name","<h1>Hello h0cksr<h1>");
moudle.addAttribute("users",Array.asList("h0cksr_1","h0cksr_2"));
return "index";
}
}
学习链接:
https://www.bilibili.com/video/BV1PE411i7CV?p=13
https://www.bilibili.com/video/BV1PE411i7CV?p=14
https://www.bilibili.com/video/BV1PE411i7CV?p=15