此博客用于个人学习,来源于网上,对知识点进行一个整理。
1. Thymeleaf :
SpringBoot 并不推荐使用 jsp,但是支持一些模板引擎技术:
- Freemarker
- Thymeleaf
- Mustache
本项目用到的是 Thymeleaf 技术。
1.1 Thymeleaf 的优势:
Thymeleaf 是一个跟 Velocity、FreeMarker 类似的模板引擎,它可以完全替代 JSP,其本身的特点有:
- 动静结合:Thymeleaf 在有网络和无网络的环境下皆可运行,即它可以让美工在浏览器查看页面的静态效果,也可以让程序员在服务器查看带数据的动态页面效果。这是由于它支持 html 原型,然后在 html 标签里增加额外的属性来达到模板+数据的展示方式。浏览器解释 html 时会忽略未定义的标签属性,所以 thymeleaf 的模板可以静态地运行;当有数据返回到页面时,Thymeleaf 标签会动态地替换掉静态内容,使页面动态显示。
- 开箱即用:它提供标准和 spring 标准两种方言,可以直接套用模板实现 JSTL、 OGNL 表达式效果,避免每天套模板、改 jstl、改标签的困扰,同时开发人员也可以扩展和创建自定义的方言。
- 多方言支持:Thymeleaf 提供 spring 标准方言和一个与 SpringMVC 完美集成的可选模块,可以快速的实现表单绑定、属性编辑器、国际化等功能。
- 与 SpringBoot 完美整合,SpringBoot 提供了 Thymeleaf 的默认配置,并且为 Thymeleaf 设置了视图解析器,可以像操作 jsp 一样来操作 Thymeleaf。代码几乎没有任何区别,就是在模板语法上有区别。
1.2 提供数据:
编写一个 controller 方法,返回一些用户数据,放入模型中,将来在页面渲染。
@GetMapping("/all")
public String all(ModelMap model) {
// 查询用户
List<User> users = this.userService.queryAll();
// 放入模型
model.addAttribute("users", users);
// 返回模板名称(就是classpath:/templates/目录下的html文件名)
return "users";
}
1.3 引入启动器:
通过 maven 引入依赖,SpringBoot 会自动为 Thymeleaf 注册一个视图解析器:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
Thymeleaf 也会根据前缀和后缀来确定模板文件的位置:

- 默认前缀:classpath:/templates/
- 默认后缀:.html
所以如果我们返回视图:users,会指向到 classpath:/templates/users.html 。
1.4 静态页面:
模板默认放在 classpath 下的 templates 文件夹,我们新建一个 html 文件放入其中,渲染模型中的数据。把 html 的名称空间,改成:xmlns:th=“http://www.thymeleaf.org” 会有语法提示。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>首页</title>
<style type="text/css">
table {border-collapse: collapse; font-size: 14px; width: 80%; margin: auto}
table, th, td {border: 1px solid darkslategray;padding: 10px}
</style>
</head>
<body>
<div style="text-align: center">
<span style="color: darkslategray; font-size: 30px">欢迎光临!</span>
<hr/>
<table class="list">
<tr>
<th>id</th>
<th>姓名</th>
<th>用户名</th>
<th>年龄</th>
<th>性别</th>
<th>生日</th>
</tr>
<tr th:each="user : ${users}">
<td th:text="${user.id}">1</td>
<td th:text="${user.name}">张三</td>
<td th:text="${user.userName}">zhangsan</td>
<td th:text="${user.age}">20</td>
<td th:text="${user.sex}">男</td>
<td th:text="${user.birthday}">1980-02-30</td>
</tr>
</table>
</div>
</body>
</html>
使用了以下语法:
- ${} :这个类似与 el 表达式,但其实是 ognl 的语法,比 el 表达式更加强大。
- th - 指令:th- 是利用了 Html5 中的自定义属性来实现的。如果不支持 H5,可以用 data-th- 来代替。
- th:each:类似于 c:foreach 遍历集合,但是语法更加简洁。
- th:text:声明标签中的文本
- 例如 <td th-text=’${user.id}’>1</td>,如果 user.id 有值,会覆盖默认的1。
- 如果没有值,则会显示 td 中默认的1。这正是 thymeleaf 能够动静结合的原因,模板解析失败不影响页面的显示效果,因为会显示默认值。
1.5 模板缓存:
Thymeleaf 会在第一次对模板解析之后进行缓存,极大的提高了并发处理能力。但是这给我们开发带来了不便,修改页面后并不会立刻看到效果,我们开发阶段可以关掉缓存使用。
# 开发阶段关闭thymeleaf的模板缓存
spring:
thymeleaf:
cache: false
在 Idea 中,我们需要在修改页面后按快捷键:Ctrl + Shift + F9 对项目进行 rebuild 才可以。
2. ES6 语法:
ECMAScript 是浏览器脚本语言的规范,而各种我们熟知的 js 语言,如 JavaScript 则是规范的具体实现。
2.1 let 和 const 命令:
之前,js 定义变量只有一个关键字:var,但这个关键字存在一个问题,就是定义的变量有时会莫名奇妙的成为全局变量。
for(var i = 0; i < 5; i++){
console.log(i);
}
console.log("循环外:" + i)
结果为
循环外:5
- let:let 所声明的变量,只在 let 命令所在的代码块内有效,将上面的代码改为 let 关键字,会出现错误。
- const:const 声明的变量是常量,不能被修改。
2.2 字符串扩展:
ES6 为字符串扩展了几个新的API:
- includes():返回布尔值,表示是否找到了参数字符串。
- startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。
- endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。
’ '来作为字符串模板标记,在两个‘之间的部分都会被作为字符串的值,不管你任意换行,甚至加入 js 脚本。
2.3 解构表达式:
-
数组解构:
比如有一个数组:
let arr = [1,2,3]如果想获取其中的值,只能通过角标。ES6 可以这样:
const [x,y,z] = arr;// x,y,z将与arr中的每个位置对应来取值 // 然后打印 console.log(x,y,z); -
对象解构:
例如有个person对象:
const person = { name:"jack", age:21, language: ['java','js','css'] }如果想获取对象的值,可以这么做:
// 解构表达式获取值 const {name,age,language} = person; // 打印 console.log(name); console.log(age); console.log(language);如过想要用其它变量接收,需要额外指定别名:
//name是person中的属性名,冒号后面的n是解构后要赋值给的变量。 const {name:n} = person; console.log(n);
2.4 函数优化:
-
函数参数默认值:
在 ES6 以前,无法给一个函数参数设置默认值,只能采用变通写法:
function add(a , b) { // 判断b是否为空,为空就给默认值1 b = b || 1; return a + b; } // 传一个参数 console.log(add(10));现在可以这么写:
function add(a , b = 1) { return a + b; } // 传一个参数 console.log(add(10)); -
箭头函数:
ES6 中定义函数的简写方式:
一个参数时:
var print = function (obj) { console.log(obj); } // 简写为: var print = obj => console.log(obj);多个参数:
// 两个参数的情况: var sum = function (a , b) { return a + b; } // 简写为: var sum = (a,b) => a+b;代码不止一行,可以用 {} 括起来:
var sum = (a,b) => { return a + b; } -
对象的函数属性简写:
比如一个 Person 对象,里面有 eat 方法:
let person = { name: "jack", // 以前: eat: function (food) { console.log(this.name + "在吃" + food); }, // 箭头函数版: eat: food => console.log(person.name + "在吃" + food),// 这里拿不到this // 简写版: eat(food){ console.log(this.name + "在吃" + food); } } -
箭头函数结合解构表达式:
比如有一个函数:
const person = { name:"jack", age:21, language: ['java','js','css'] } function hello(person) { console.log("hello," + person.name) }如果用箭头函数和解构表达式
var hi = ({name}) => console.log("hello," + name);
2.5 map 和 reduce:
-
map:
map() :接收一个函数,将原数组中的所有元素用这个函数处理后放入新数组返回。
举例:有一个字符串数组,我们希望转为 int 数组。
let arr = ['1','20','-5','3']; console.log(arr) arr = arr.map(s => parseInt(s)); console.log(arr) -
reduce:
reduce() :接收一个函数(必须)和一个初始值(可选)。
第一个参数(函数)接收两个参数:第一个参数是上一次 reduce 处理的结果;第二个参数是数组中要处理的下一个元素。
reduce() 会从左到右依次把数组中的元素用 reduce 处理,并把处理的结果作为下次 reduce 的第一个参数。如果是第一次,会把前两个元素作为计算参数,或者把用户指定的初始值作为起始参数。
举例:
const arr = [1,20,-5,3]没有初始值:
arr.reduce((a,b) => a+b)结果是 19。
指定初始值:
arr.reduce((a,b) => a+b,1)结果是 20。
2.6 对象扩展:
ES6 给 Object 拓展了许多新的方法,如:
- keys(obj):获取对象的所有 key 形成的数组。
- values(obj):获取对象的所有 value 形成的数组。
- entries(obj):获取对象的所有 key 和 value 形成的二维数组。格式:[[k1,v1],[k2,v2],…]
- assign(dest, …src) :将多个 src 对象的值 拷贝到 dest 中(浅拷贝)。
2.7 数组扩展:
ES6 给数组新增了许多方法:
- find(callback):数组实例的 find 方法,用于找出第一个符合条件的数组成员。它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为 true 的成员,然后返回该成员。如果没有符合条件的成员,则返回 undefined。
- findIndex(callback):数组实例的 findIndex 方法的用法与 find 方法非常类似,返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1。
- includes(数组元素):与 find 类似,如果匹配到元素,则返回 true,代表找到了。
本文主要探讨Thymeleaf模板引擎的优势及在SpringBoot中的使用,包括数据提供、启动器引入、静态页面处理和模板缓存。同时,文章也详细介绍了ES6的语法特性,如let和const、字符串扩展、解构表达式、函数优化、map和reduce等,帮助读者深入理解这两个技术。
779

被折叠的 条评论
为什么被折叠?



