- 只要静态资源放在类路径下:?
/static?
or?/public
?or?/resources
?or?/META-INF/resources
- 访问?: 当前
项目根路径/ + 静态资源名
- 原理: 静态映射
/**
;?"/**" 访问当前项目的任何资源 (静态资源的文件夹)
- 请求进来,先去找Controller看能不能处理。不能处理的所有请求又都交给静态资源处理器。静态资源也找不到则响应404页面
源码解析
我们也可以自己通过配置文件来指定一下,哪些文件夹是需要我们放静态资源文件的,在application.properties中配置;
spring.resources.static-locations=classpath:/coding/,classpath:/yanyu/
spring:
resources:
static-locations: [classpath:/haha/]
默认无前缀
spring:
mvc:
static-path-pattern: /res/**
访问地址:当前项目 + static-path-pattern + 静态资源名 = 静态资源文件夹下找的对应文件名
?这是一个Spring Boot应用程序的配置文件项,用于指定静态资源的加载路径。在这个例子中,有两个静态资源文件夹:
classpath:/coding/
和classpath:/yanyu/
。当访问这些路径时,Spring Boot会自动从类路径(classpath)下查找对应的资源文件。
?总结?
?1.在springboot,我们可以使用以下方式处理静态资源
- Webjars localhost:8080/webjars/
- ?public,static,/**resources localhost:8080/
2.优先级:resources>static(默认)>public
欢迎页,静态资源文件夹下的所有 index.html 页面;被 /** 映射。
比如我访问 ?http://localhost:8080/ ,就会找静态资源文件夹下的 index.html
- 图片文件名必须为
favicon.ico
- 图片文件必须放在
静态资源目录下
dev-tools
就不用重启项目了
使用:Ctrl+F9(重构项目);
//导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
Spring Boot支持多种模板引擎,包括Thymeleaf、FreeMarker、Velocity和Mustache等。这些模板引擎都可以与Spring Boot无缝集成,用于生成动态HTML页面。
Thymeleaf是Spring Boot官方推荐的模板引擎,它是一个现代化的服务器端Java模板引擎,使用自然模板语法简化模板设计和开发。Thymeleaf可以直接与Spring MVC集成,也可以与Spring WebFlux一起使用。
特点
- 动静分离:?Thymeleaf选用html作为模板页,这是任何一款其他模板引擎做不到的!Thymeleaf使用html通过一些特定标签语法代表其含义,但并未破坏html结构,即使无网络、不通过后端渲染也能在浏览器成功打开,大大方便界面的测试和修改。
- 开箱即用:?Thymeleaf提供标准和Spring标准两种方言,可以直接套用模板实现JSTL、 OGNL表达式效果,避免每天套模板、改JSTL、改标签的困扰。同时开发人员也可以扩展和创建自定义的方言。
- Springboot官方大力推荐和支持,Springboot官方做了很多默认配置,开发者只需编写对应html即可,大大减轻了上手难度和配置复杂度。
// 使用@ConfigurationProperties注解,将配置文件中的属性绑定到这个类的属性上
@ConfigurationProperties(
prefix = "spring.thymeleaf"
)
public class ThymeleafProperties {
// 定义一个静态常量DEFAULT_ENCODING,表示默认的字符编码
private static final Charset DEFAULT_ENCODING;
// 定义一个静态常量DEFAULT_PREFIX,表示默认的模板文件前缀
public static final String DEFAULT_PREFIX = "classpath:/templates/";
// 定义一个静态常量DEFAULT_SUFFIX,表示默认的模板文件后缀
public static final String DEFAULT_SUFFIX = ".html";
// 定义一个布尔类型的属性checkTemplate,表示是否检查模板文件是否存在
private boolean checkTemplate = true;
// 定义一个布尔类型的属性checkTemplateLocation,表示是否检查模板文件的位置是否正确
private boolean checkTemplateLocation = true;
// 定义一个字符串类型的属性prefix,表示模板文件的前缀
private String prefix = "classpath:/templates/";
// 定义一个字符串类型的属性suffix,表示模板文件的后缀
private String suffix = ".html";
// 定义一个字符串类型的属性mode,表示模板引擎的模式,默认为HTML模式
private String mode = "HTML";
// 定义一个Charset类型的属性encoding,表示模板文件的字符编码
private Charset encoding;
}
我们可以在其中看到默认的前缀和后缀!
我们只需要把我们的html页面放在类路径下的templates下,thymeleaf就可以帮我们自动渲染了。
使用thymeleaf什么都不需要配置,只需要将他放在指定的文件夹下即可
后端
package com.yanyu.springplustest4;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class TestController {
@RequestMapping("/t1")
public String test1(){
//classpath:/templates/test.html
return "test";
}
}
前端
?test.html 放在 templates 目录下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>测试页面</h1>
</body>
咱们在项目的resources目录下的templates文件夹下面创建一个叫index.html的文件,咱们在这个html文件中的<html>标签修改为<html xmlns:th="http://www.thymeleaf.org">这样在Thymeleaf中就可以使用Thymeleaf的语法和规范啦。
后端
package com.yanyu.springplustest4;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class urlController {
@GetMapping("t2")//页面的url地址
public String getindex(Model model)//对应函数
{
model.addAttribute("name","bigsai");
return "test2";//与templates中index.html对应
}
}
前端
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>title</title>
</head>
<body>
hello 第一个Thymeleaf程序
<div th:text="${name}">name是bigsai(我是离线数据)</div>
</body>
</html>
Springboot官方对Thymeleaf做了很多默认配置,但咱们引入Thymeleaf的jar包依赖后很可能根据自己特定需求进行更细化的配置,例如页面缓存、字体格式设置等等。
Springboot官方提供的配置内容有以下:
# THYMELEAF (ThymeleafAutoConfiguration)
spring.thymeleaf.cache=true# 是否启用模板缓存
spring.thymeleaf.check-template=true# 在渲染模板之前检查模板是否存在
spring.thymeleaf.check-template-location=true # 在渲染模板之前检查模板位置是否存在
spring.thymeleaf.enabled=true # 是否为Web框架启用Thymeleaf视图解析
spring.thymeleaf.enable-spring-el-compiler=false # 在SpringEL表达式中启用SpringEL编译器
spring.thymeleaf.encoding=UTF-8 # 模板文件的编码
spring.thymeleaf.excluded-view-names= # 从解析中排除的视图名称(允许的模式)列表
spring.thymeleaf.mode=HTML # 应用于模板的模式
spring.thymeleaf.prefix=classpath:/templates/ # 构建URL时附加到视图名称的前缀
# 当设置最大块大小时,仅在CHUNKED模式下执行的视图名称(模式)列表
spring.thymeleaf.reactive.chunked-mode-view-names=
# 即使设置了最大块大小,也应在FULL模式下执行的视图名称(模式)列表
spring.thymeleaf.reactive.full-mode-view-names=
spring.thymeleaf.reactive.max-chunk-size=0 # 用于写入响应的数据缓冲区的最大大小(字节)
spring.thymeleaf.reactive.media-types= # 视图技术支持的媒体类型
spring.thymeleaf.servlet.content-type=text/html # 写入HTTP响应的Content-Type值
spring.thymeleaf.suffix=.html # 构建URL时附加到视图名称的后缀
spring.thymeleaf.template-resolver-order= # 链中的模板解析器顺序
spring.thymeleaf.view-names= # 可以解析的视图名称(模式)列表
比如
spring.thymeleaf.cache=false
是否允许页面缓存的配置,我们在开发时候要确保页面是最新的所以需要禁用缓存;而在上线运营时可能页面不常改动为了减少服务端压力以及提升客户端响应速度会允许页面缓存的使用。
咱们上面知道Thymeleaf通过特殊的标签来寻找属于Thymeleaf的部分,并渲染该部分内容,而除了上面展示过的th:text之外还有很多常用标签,并且Thymeleaf也主要通过标签来识别替换对应位置内容,Thymeleaf标签有很多很多,功能也很丰富,这里列举一些比较常用的标签如下:
标签 | 作用 | 示例 |
---|---|---|
th:id | 替换id | <input th:id="${user.id}"/> |
th:text | 文本替换 | <p text:="${user.name}">bigsai</p> |
th:utext | 支持html的文本替换 | <p utext:="${htmlcontent}">content</p> |
th:object | 替换对象 | <div th:object="${user}"></div> |
th:value | 替换值 | <input th:value="${user.name}" > |
th:each | 迭代 | <tr th:each="student:${user}" > |
th:href | 替换超链接 | <a th:href="@{index.html}">超链接</a> |
th:src | 替换资源 | <script type="text/javascript" th:src="@{index.js}"></script> |
后端
数据层
package com.yanyu.springplustest4.dto;
import lombok.Data;
import java.util.List;
@Data
public class User {
private int id;
private String name;
private boolean active;
private List<String> students;
}
控制层?
package com.yanyu.springplustest4.Controller;
import com.yanyu.springplustest4.dto.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.Arrays;
@Controller
public class UserController {
@GetMapping("/user")
public String getUser(Model model) {
User user = new User();
user.setId(1);
user.setName("John Doe");
user.setActive(true);
user.setStudents(Arrays.asList("Alice", "Bob", "Charlie"));
model.addAttribute("user", user);
model.addAttribute("msg","Hello,Thymeleaf");
return "user";
}
}
前端
<!-- DOCTYPE html -->
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>User Page</title>
</head>
<body>
<!-- 表单提交,action指向/user,object绑定到user对象 -->
<form method="post" th:action="@{/user}" th:object="${user}">
<!-- 输入框,id绑定到user的id属性,value绑定到user的name属性,name属性为name -->
<input th:id="${user.id}" th:value="${user.name}" name="name" />
<!-- 显示用户姓名 -->
<p th:text="${user.name}">bigsai</p>
<!-- 显示消息内容 -->
<p th:utext="${msg}">content</p>
<!-- 显示user对象的内容 -->
<div th:object="${user}"></div>
<!-- 输入框,值为user的name属性 -->
<input th:value="${user.name}" >
<!-- 表格,遍历user的students属性 -->
<table>
<tr th:each="student : ${user.students}">
<!-- 显示学生姓名 -->
<td th:text="${student}">Student Name</td>
</tr>
</table>
<!-- 链接,指向index.html -->
<a th:href="@{index.html}">Link</a>
<!-- 提交按钮 -->
<button type="submit">Update</button>
<!-- 如果user的active属性为true,则显示取消激活按钮,调用deactivateUser方法并传入user的id属性 -->
<button type="button" th:if="${user.active}" th:"deactivateUser(${user.id})">Deactivate</button>
</form>
</body>
</html>
在这个示例中,当访问/user路径时,UserController会将一个User对象添加到Model中,然后返回user.html模板文件。在user.html中,利用Thymeleaf的th:id属性替换了input标签的id属性,使得input标签的id值根据User对象的id属性动态变化。同时,form标签的method属性设置为post,action属性设置为"/user",表示表单提交的目标地址为UserController的updateUser方法。在表单中,利用name属性指定了表单项的名称,使得在提交表单时可以正确地绑定到User对象的属性上。
<link rel="stylesheet" th:href="@{index.css}">
<script type="text/javascript" th:src="@{index.js}"></script>
<a th:href="@{index.html}">超链接</a>
在Thymeleaf中可以通过${…}进行取值,这点和ONGL表达式语法一致。
例如咱们创建这么一个对象:
package com.yanyu.springplustest4.dto;
import lombok.Data;
@Data
public class user {
private String name;
private int age;
private String detail;
}
控制层
package com.yanyu.springplustest4.Controller;
import com.yanyu.springplustest4.dto.user1;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Controller
public class UserControlle1 {
@GetMapping("/user1")//页面的url地址
public String getindex(Model model)//对应函数
{
user1 user1=new user1("bigsai",22,"一个幽默且热爱java的社会青年");
List<String> userList=new ArrayList<>();
userList.add("zhang san 66");
userList.add("li si 66");
userList.add("wang wu 66");
Map<String ,String> map=new HashMap<>();
map.put("place","博学谷");
map.put("feeling","very well");
//数据添加到model中
model.addAttribute("name","bigsai");//普通字符串
model.addAttribute("user",user1);//储存javabean
model.addAttribute("userlist",userList);//储存List
model.addAttribute("map",map);//储存Map
return "user1";//与templates中index.html对应
}
}
取普通字符串:
如果在controller中的Model直接存储某字符串,我们可以直接${对象名}
进行取值。完整代码如下:
<h2>普通字符串</h2>
<table border="0">
<tr>
<td th:text="'我的名字是:'+${name}"></td>
</tr>
</table>
取JavaBean对象:
取JavaBean对象也很容易,因为JavaBean自身有一些其他属性,所以咱们就可以使用${对象名.对象属性}
或者${对象名['对象属性']}
来取值,这和JavaScript语法是不是很相似呢!除此之外,如果该JavaBean如果写了get方法,咱们也可以通过get方法取值例如${对象.get方法名}
完整代码如下:
<h2>JavaBean对象</h2>
<table bgcolor="#ffe4c4" border="1">
<tr>
<td>介绍</td>
<td th:text="${user.name}"></td>
</tr>
<tr>
<td>年龄</td>
<td th:text="${user['age']}"></td>
</tr>
<tr>
<td>介绍</td>
<td th:text="${user.getDetail()}"></td>
</tr>
</table>
取List集合(each):
因为List集合是个有序列表,里面内容可能不止一个,你需要遍历List对其中对象取值,而遍历需要用到标签:th:each,具体使用为<tr th:each="item:${userlist}">,其中item就相当于遍历每一次的对象名,在下面的作用域可以直接使用,而userlist就是你在Model中储存的List的名称。完整的代码为
<h2>List取值</h2>
<table bgcolor="#ffe4c4" border="1">
<tr th:each="item:${userlist}">
<td th:text="${item}"></td>
</tr>
</table>
直接取Map:
很多时候我们不存JavaBean而是将一些值放入Map中,再将Map存在Model中,我们就需要对Map取值,对于Map取值你可以${Map名['key']}来进行取值。也可以通过${Map名.key}取值,当然你也可以使用${map.get('key')}(java语法)来取值,完整代码如下:
<h2>Map取值</h2>
<table bgcolor="#8fbc8f" border="1">
<tr>
<td>place:</td>
<td th:text="${map.get('place')}"></td>
</tr>
<tr>
<td>feeling:</td>
<td th:text="${map['feeling']}"></td>
</tr>
</table>
遍历Map:
如果说你想遍历Map获取它的key和value那也是可以的,这里就要使用和List相似的遍历方法,使用th:each="item:${Map名}"
进行遍历,在下面只需使用item.key
和item.value
即可获得值。完整代码如下:
<h2>Map遍历</h2>
<table bgcolor="#ffe4c4" border="1">
<tr th:each="item:${map}">
<td th:text="${item.key}"></td>
<td th:text="${item.value}"></td>
</tr>
</table>
变量表达式不仅可以写成${…},而且还可以写成*{…}。
但是,有一个重要的区别:星号语法对选定对象而不是整个上下文评估表达式。也就是说,只要没有选定的对象,美元(${…})和星号(*{...})的语法就完全一样。
什么是选定对象?使用th:object属性的表达式的结果。就可以选定对象,具体实例
<!-- 使用Thymeleaf模板引擎,将user对象绑定到div元素上 -->
<div th:object="${user}">
<!-- 显示用户姓名,如果不存在则显示默认值"赛" -->
<p>Name: <span th:text="*{name}">赛</span>.</p>
<!-- 显示用户年龄,如果不存在则显示默认值"18" -->
<p>Age: <span th:text="*{age}">18</span>.</p>
<!-- 显示用户的详细信息,如果不存在则显示默认值"好好学习" -->
<p>Detail: <span th:text="*{detail}">好好学习</span>.</p>
</div>
文本外部化是从模板文件中提取模板代码的片段,以便可以将它们保存在单独的文件(通常是.properties文件)中,文本的外部化片段通常称为“消息”。通俗易懂的来说#{…}
语法就是用来读取配置文件中数据的。在Thymeleaf你可以使用#{...}
语法获取消息,具体实例代码如下:
首先在templates目录下建立home.properties
中写入以下内容:
bigsai.nane=bigsai
bigsai.age=22
province=Jiang Su
在application.properties
中加入以下内容:
spring.messages.basename=templates/home
这样我们就可以在Thymeleaf中读取配置的文件了,完整代码如下:
<h2>消息表达</h2>
<table bgcolor="#ffe4c4" border="1">
<tr>
<td>name</td>
<td th:text="#{bigsai.name}"></td>
</tr>
<tr>
<td>年龄</td>
<td th:text="#{bigsai.age}"></td>
</tr>
<tr>
<td>province</td>
<td th:text="#{province}"></td>
</tr>
</table>