亮点
thymeleaf向往自然模板,它的模板html文件,完全可以作为html页面在项目中显示出来。
freemarker的ftl文件,从这点上看,没有thymeleaf方便。
语法
thymeleaf的语法非常简单,学习它的语法,首先要明确它的本质,把model中的数据渲染到html中,因此语法主要就是解析model中的数据,一句话概括,类似于JSP页面中的${abc},老程序员们的福利。
关于thymeleaf语法知识,我只说几个重点,举几个重点例子,足够大家使用了。
变量
实体类User
package com.laoben.demo.entity;
import lombok.Data;
@Data
public class User {
String name;
int age;
String sex;
String role;
User friend;
public User() {
}
public User(String name, int age, String sex, User friend) {
this.name = name;
this.age = age;
this.sex = sex;
this.friend = friend;
}
}
后台
@GetMapping("bianliang")
public String demo1(Model model){
User laoben = new User();
User qinqin = new User("qinqin",16,laoben);
laoben.setAge(18);
laoben.setName("小老犇");
laoben.setFriend(qinqin);
model.addAttribute("user", laoben);
return "bianliang";
}
前端
<!--变量-->
<h1>
欢迎您:<span th:text="${user.name}">请登录</span>
</h1>
结果
我们看到了${user.name},和EL表达式简直一模一样,但是这个不是EL,而是OGNL表达式。
而且我们注意到了新的标签,th:text,在thymeleaf中,这个标签叫做指令,thymeleaf的任何表达式都要在th:指令中才可以正常运行。
项目结构可以参考我的这篇博客:
https://blog.youkuaiyun.com/numbbe/article/details/109373596
整个项目稍后,我会上传到优快云资源里,欢迎大家下载!
自定义变量
后台
@GetMapping("zidingyiBL")
public String zidingyiBL(Model model){
User laoben = new User();
User qinqin = new User("qinqin",16,laoben);
laoben.setAge(18);
laoben.setName("小老犇");
laoben.setFriend(qinqin);
model.addAttribute("user", laoben);
return "zidingyiBL";
}
前端
<!--自定义变量-->
<h1 th:object="${user}">
<p>Name: <span th:text="*{name}">xiaolaoben</span>.</p>
<p>Age: <span th:text="*{age}">18</span>.</p>
<p>friend: <span th:text="*{friend.name}">laowang</span>.</p>
</h1>
结果
一个用户,会有很多基本信息,每个信息都是一个字段,我们想要在页面进行渲染时,每次都要重复的写
u
s
e
r
.
a
g
e
,
{user.age},
user.age,{user.school},${user.name},看着没有b格,thymeleaf支持自定义变量,页面中的变量。
我们注意到了h2标签中多了th:object指令。
h2标签内部任何属性都可以直接使用对象的属性,省去对象.属性。前边只需要加上*即可。
方法
后台
@GetMapping("fangfa")
public String fangfa(Model model){
User laoben = new User();
User qinqin = new User("qinqin",16,laoben);
laoben.setAge(18);
laoben.setName("bawang");
laoben.setFriend(qinqin);
model.addAttribute("user", laoben);
model.addAttribute("today", new Date());
return "fangfa";
}
前端
<!--方法-->
<!--String类split方法-->
<!--split方法参数为正则表达式-->
<h1 th:object="${user}">
<p>FirstName: <span th:text="*{name.split('n')[0]}">LaoBen</span></p>
<p>LastName: <span th:text="*{name.split('a')[1]}">Xiao</span></p>
</h1>
<hr>
<!--Date类格式化-->
<p>
today is: <span th:text="${#dates.format(today,'yyyy-MM-dd')}">2020-11-1</span>
</p>
结果
OGNL表达式支持方法调用,比如最常见的String类的split方法。
Thymeleaf提供了一些内置对象,每个对象都有一些方法,方便我们进行调用。获取对象时,#对象名,这样使用。
环境相关对象
#ctx 获取Thymeleaf自己的Context对象 `
#requset 如果是web程序,可以获取HttpServletRequest对象
#response 如果是web程序,可以获取HttpServletReponse对象
#session 如果是web程序,可以获取HttpSession对象
#servletContext 如果是web程序,可以获取HttpServletContext对象
全局对象
#lists 处理List集合的方法
#sets 处理set集合的方法
#maps 处理map集合的方法
#bools 判断布尔值的方法
#dates 处理java.util.date的工具对象
#calendars 处理java.util.calendar的工具对象
#numbers 对数字格式化的方法
#strings 处理字符串的方法
#arrays 处理数组的方法
字面值
后台
@GetMapping("zimianzhi")
public String zimianzhi(Model model){
User laoben = new User();
User qinqin = new User("qinqin",16,laoben);
laoben.setAge(18);
laoben.setName("小老犇");
laoben.setFriend(qinqin);
model.addAttribute("user", laoben);
return "zimianzhi";
}
前端
<!--字面值-->
<p>
my name is <span th:text="'xiaolaoben'">template</span> -----这里是字符串字面值.
</p>
<p>今年是 <span th:text="2020">1921</span>.</p>
<p>百年后是 <span th:text="3018 + 2">1902</span>-----这里是数字字面值.</p>
结果
指令中的字符串一般被解析为变量,但有的时候我们想增加一些文字描述,这些字符串不希望被解析为变量,一般称其为字面值。
-
一对‘’引用的内容就是字符串字面值。
-
数字字面值没有语法。
拼接
后台
@GetMapping("pinjie")
public String pinjie(Model model){
User laoben = new User();
User qinqin = new User("qinqin",16,laoben);
laoben.setAge(18);
laoben.setName("小老犇");
laoben.setFriend(qinqin);
model.addAttribute("user", laoben);
return "pinjie";
}
前端
<!--拼接-->
<p><span th:text="'最帅:' + ${user.name}"></span></p>
<p><span th:text="|最帅:${user.name}|"></span>-----这里是字符串拼接.</p>
结果
运算
后端
@GetMapping("yunsuan")
public String yunsuan(Model model){
User laoben = new User();
User qinqin = new User("qinqin",16,"仙女",laoben);
laoben.setAge(18);
laoben.setSex("男");
laoben.setFriend(qinqin);
model.addAttribute("user", laoben);
return "yunsuan";
}
前端
<!--运算-->
<p>年龄:<span th:text="${user.age}"></span></p>
<p>算术运算符:<span th:text="${user.age}%2 == 0"></span></p>
<p>比较运算符:<span th:text="${user.age}%2 gt 0"></span></p>
<p>三元运算符:<span th:text="${user.sex} ? '男':'女'"></span></span></p>
<p>三元运算符参数为空默认值:<span th:text="${user.name} ?: '小老犇爱琴琴'"></span></p>
结果
{}内部是通过OGNL表达式解析的,外部是Thymeleaf引擎解析,运算符属于Thymeleaf的东西,所以要放在${}外边进行。
常用的运算符有三种:
算数运算符:+ - * / %
比较运算符:>,<,>=,<=,==,在thymeleaf中,>这种符号会被xml解析为标签,所以使用的时候使用别名,具体使用方法参考下面示例。
gt (>), lt (<), ge (>=), le (<=), not (!),eq (==), neq (!=)
条件运算符: 如三元运算符。
循环
后台
@GetMapping("xunhuan")
public String xunhuan(Model model){
User laoben = new User();
User qinqin = new User("qinqin",16,"仙女",laoben);
User laowang = new User("laowang",30,"禽兽",laoben);
laoben.setAge(18);
laoben.setName("小老犇");
laoben.setSex("男");
laoben.setFriend(qinqin);
List<User> users = new ArrayList<User>();
users.add(laoben);
users.add(qinqin);
users.add(laowang);
model.addAttribute("users", users);
return "xunhuan";
}
前端
<!--循环-->
<tr th:each="user : ${users}">
<td th:text="${user.name}">欧尼酱</td>
<td th:text="${user.age}">199</td>
</tr>
结果
th:each指令。
${users} 是要遍历的集合,可以是以下类型:
- Iterable,实现了Iterable接口的类。
- Enumeration,枚举。
- Interator,迭代器。
- Map,Map。
- Array,数组。
逻辑判断
后台
@GetMapping("luoji")
public String luoji(Model model){
User laoben = new User();
User qinqin = new User("qinqin",16,"仙女",laoben);
laoben.setAge(18);
laoben.setSex("男");
laoben.setFriend(qinqin);
model.addAttribute("user", laoben);
return "luoji";
}
前端
<!--逻辑判断-->
<p>使用大于符号时不满足条件,不解析标签内容,不渲染:<span th:if="${user.age} gt 26">小老犇</span></body></p>
<p>使用小于符号时满足条件,解析标签内容,渲染:<span th:if="${user.age} lt 26">小老犇</span></body></p>
结果
逻辑判断如上所示共有两个指令:th:if,th:unless。
分支控制
后台
@GetMapping("fenzhi")
public String fenzhi(Model model){
User laoben = new User();
User qinqin = new User("qinqin",16,"仙女",laoben);
laoben.setAge(18);
laoben.setSex("男");
laoben.setRole("admin");
laoben.setFriend(qinqin);
model.addAttribute("user", laoben);
return "fenzhi";
}
前端
<!--分支控制-->
<div th:switch="${user.role}">
<p th:case="'manager'">用户是用户(呆瓜)</p>
<p th:case="'admin'">用户是小老犇,累死我了(哭笑脸)</p>
<p th:case="*">用户不是管理员也不是用户(滑稽脸)</p>
//最后这一样表示默认的,啥也不是就走这个了。
</div>
结果
分支控制共有两个指令:th:switch,th:case。
注意一点:该指令与Java中的switch一样的,一旦有一个th:case成立,其它的则不再判断,直接break。
···································································
本文到了这里就结束了,项目源码放在了我的主页资源里,有需要的自取哦。