文章目录
- 前言
- 一 Thymeleaf 介绍
-
- 1.1 概念
- 1.2 特点
- 二 Thymeleaf详解
-
- 1 表达式
-
- 1.1 变量表达式
- 1.2 选择表达式
- 1.3 URL表达式
-
- 1.3.1 url表达式
- 1.3.2 文本替换
- 1.3.2 字符串拼接
- 1.4 表达式常见用法
- 1.5 常用th标签
- 1.6 基本用法
-
- 1.6.1 赋值、字符串拼接
- 1.6.2 条件判断if/unless
- 1.6.3 for循环
- 1.6.4 status状态变量
- 1.6.5 内联文本
- 1.6.6 内联文本
- 1.6.7 内嵌对象
- 1.6.8 布局
- 三 Thymeleaf入门案例
-
- 1启动器
- 2 pom.xml
- 3 配置文件
- 4 相关的静态文件
- 5 后台UserController
- 6 实体类User
- 7 UserMapper
- 8 UserService
- 9 UserServiceImpl
- 四 测试结果
-
- 1 循环
- 2 布局、内置对象和其他指令
前言 本篇记录我在学习SpringBoot的过程中,对Thymeleaf的学习经验;
Thymeleaf是一种 提示:以下是本篇文章正文内容,下面案例可供参考
一 Thymeleaf 介绍 1.1 概念 Thymeleaf 是一个跟 FreeMarker 类似的模板引擎,它可以完全替代 JSP 。;
1.2 特点
- 动静结合:Thymeleaf 在有网络和无网络的环境下皆可运行,无网络显示静态内容,有网络用后台得到数据替换静态内容;
- 与SpringBoot完美整合,springboot默认整合thymelea
1.1 变量表达式
就是OGNL表达式或者Spring EL表达式(spring中在jsp页面中获取session或其他内置对象的数据)如:${session.user.name};
它们将以HTML标签的一个属性来表示:
表达式
>${text}
th:text="${text}">你好 thymleaf
1.2 选择表达式
也可以叫星号表达式,有点像变量表达式,不过它们用一个预先选择的对象来代替上下文变量容器(map)来执行,如: *{customer.name};被指定的对象object由th:object属性定义,
代码如下:
true
true
0
1
1
zhangsan
张三
20
男
1980-02-30 1
删除修改审核
1.3 URL表达式
- URL表达式指的是把一个有用的上下文或回话信息添加到URL,这个过程经常被叫做URL重写。
- URL还可以设置参数: @{/order/details(id=${orderId}, name=*{name})
删除
1.3.2 文本替换
修改
1.3.2 字符串拼接
审核
1.4 表达式常见用法
字面(Literals)
- 文本文字(Text literals): ‘one text’, ‘Another one!’,…
- 数字文本(Number literals): 0, 34, 3.0, 12.3,…
- 布尔文本(Boolean literals): true, false
- 空(Null literal): null文字标记(Literal tokens): one, sometext, main,…
- 文本操作(Text operations)
- 字符串连接(String concatenation): +
- 文本替换(Literal substitutions): |The name is ${name}|
- 算术运算(Arithmetic operations)
- 二元运算符(Binary operators): +, -, *, /, %
- 减号(单目运算符)Minus sign (unary operator): -
- 布尔操作(Boolean operations)
- 二元运算符(Binary operators): and, or
- 布尔否定(一元运算符)Boolean negation (unary operator): !, not
- 比较和等价(Comparisons and equality)
- 比较(Comparators): >, <, >=, <= (gt, lt, ge, le)
- 等值运算符(Equality operators): ==, != (eq, ne)
- 条件运算符(Conditional operators)
- If-then: (if) ? (then)
- If-then-else: (if) ? (then) : (else)
- Default: (value) ?: (defaultvalue)
关键字 | 功能介绍 | 案例 |
---|---|---|
th:text | 文本替换 | < p th:text="${collect.description}">description< /p > |
th:id | 替换id | < input th:id="‘xxx’ + ${collect.id}"/ > |
th:utext | 支持html的文本替换 | < p th:utext="${htmlcontent}">conten< /p > |
th:object | 替换对象 | < div th:object="${session.user}"> |
th:value | 属性赋值 | < input th:value="https://www.it610.com/article/${user.name}" /> |
th:with | 变量赋值运算 | < div th:with=“isEven=${prodStat.count}%2==0”>< /div> |
th:style | 设置样式 | th:style="‘display:’ + @{(${sitrue} ? ‘none’ : ‘inline-block’)} + ‘’" |
th:onclick | 点击事件 | th:οnclick="‘getCollect()’" |
th:each | 属性赋值 | tr th:each=“user,userStat:${users}”> |
th:if | 判断条件 | < a th:if="${userId == collect.userId}" > |
th:unless | 和th:if判断相反 | < a th:unless="${userId == collect.userId}" > |
th:href | 链接地址 | |
th:switch | 多路选择 配合th:case使用 | < div th:switch="${user.role}" |
th:case | th:switch的一个分支 | < p th:case="‘admin’">User is an administrator< /p> |
th:fragment | 布局标签,定义一个代码片段,方便其它地方引用 | < div th:fragment=“alert”> |
th:include | 布局标签,替换内容到引入的文件 | < head th:include=“layout :: htmlhead” th:with=“title=‘xx’”>< /head> |
th:replace | 布局标签,替换整个标签到引入的文件 | < div th:replace=“fragments/header :: title”>< /div> |
th:selected | selected选择框 选中 | th:selected="( {configObj.dd})" |
th:src | 图片类地址引入< img class=“img-responsive” alt=“App Logo” th:src="https://www.it610.com/article/@{/img/logo.png}" /> | |
th:inline | 定义js脚本可以使用变量 | < script type=“text/javascript” th:inline=“javascript”> |
th:action | 表单提交的地址 | < form action=“subscribe.html” th:action="@{/subscribe}"> |
th:remove | 删除某个属性 | < tr th:remove=“all”> 1.all:删除包含标签和所有的孩子。2.body:不包含标记删除,但删除其所有的孩子。3.tag:包含标记的删除,但不删除它的孩子。4.all-but-first:删除所有包含标签的孩子,除了第一个。5.none:什么也不做。这个值是有用的动态评估。 |
th:attr | 设置标签属性,多个属性可以用逗号分隔 | th:attr=“src=https://www.it610.com/article/@{/image/aa.jpg},title=#{logo}”,此标签不太优雅,一般用的比较少。 |
1.6.1 赋值、字符串拼接
修改
审核
1.6.2 条件判断if/unless if是条件成立是生效,unless是条件不成立是生效,两者恰好相反
if指令
查询结果存在
查询结果不存在
登录
1.6.3 for循环
true
true
0
1
1
zhangsan
张三
20
男
1980-02-30 1
删除修改审核
1.6.4 status状态变量
- index:当前迭代对象的index(从0开始计算)
- count: 当前迭代对象的index(从1开始计算)
- size:被迭代对象的大小
- current:当前迭代变量
- even/odd:布尔值,当前循环是否是偶数/奇数(从0开始计算)
- first:布尔值,当前循环是否是第一个
- last:布尔值,当前循环是否是最后一个
父级标签内使用,甚至作为body的标签。内联文本尽管比th:text的代码少,不利于原型显示。使用的内容必须是后端返回的model总有的内容;
- 在thymeleaf指令中显示
静态内容
- 使用内联文本显示model attribute
内联文本
[[${text}]]
[[${text}]]
[[${text}]]
**PS:**能用th指令就用替换指令
1.6.6 内联文本 与内联文本相似,以th:inline=”text/javascript/none”激活,内容是js脚本。拥有js脚本的能力;
内联js
th:inline="javascript">
var text = '[[${text}]]';
console.log(text);
1.6.7 内嵌对象 Thymeleaf提供了了一系列Utility对象(内置于Context中),可以通过**# + 对象名**的方式直接调用其中的方法。
对象 | 功能 |
---|---|
dates | java.util.Date**的功能方法类。 |
calendars | 类似#dates,面向java.util.Calendar |
numbsers | 格式化数字的功能方法类 |
strings | 字符串对象的功能类 |
objects | 对objects的功能类操作。 |
bools | 对布尔值求值的功能方法。 |
arrays | 对数组的功能类方法。 |
lists/sets/maps/ | 对list/set/map功能类方法 |
然后,在页面任何地方引入:
thymeleaf布局
- th:insert :保留自己的主标签,保留th:fragment的主标签。
- th:replace :不要自己的主标签,保留th:fragment的主标签。
- th:include :保留自己的主标签,不要th:fragment的主标签。
org.springframework.boot
spring-boot-starter-thymeleaf
2 pom.xml
4.0.0 com.kaikeba
sb-thymeleaf-01
1.0-SNAPSHOT org.springframework.boot
spring-boot-starter-parent
2.3.11.RELEASE
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
org.springframework.boot
spring-boot-starter-thymeleaf
tk.mybatis
mapper-spring-boot-starter
2.1.5
mysql
mysql-connector-java
8.0.25
3 配置文件 application.properties
server.port=8080
logging.level.com.kaikeba=debug
# 数据库信息
spring.datasource.url=jdbc:mysql://localhost:3306/springboot-jdbc?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT
spring.datasource.password=root
spring.datasource.username=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 关闭thymeleaf缓存
spring.thymeleaf.cache=false
4 相关的静态文件 由于springboot为thymeleaf自动添加的视图解析器会加上templates前缀,所以我们的所有静态文件都必须在**/resources/templates/** 下,
文章图片
定义的布局footer.html:
测试的temp.html:
Title - 锐客网 Thymeleaf布局内置变量
th:text="${#dates.format(#dates.createNow(), 'yyyy-MM-dd HH:mm:ss')}">获取当前日期
th:text="${#strings.substring(text, 4, 6)}">截取字符串
th:text="${#strings.length(text)}">
th:text="${#strings.randomAlphanumeric(6)}">随机字符串
th:text="${#strings.equals(text, 'hello')}">equals等值判断
if指令
查询结果存在
查询结果不存在
登录
内联文本
th:text="${text}">静态内容
${text}
[[${text}]]
内联JS
>内容在console.log
th:inline="javascript">
var text = '[[${text}]]';
console.log(text);
测试循环的user.html:
Thymeleaf 入门案例 - 锐客网
type="text/css">
table {
border-collapse: collapse;
font-size: 15px;
width: 80%;
margin: auto;
}table, th, td {
border: 1px solid darkslategray;
padding: 10px
}
5 后台UserController
package com.kaikeba.controller;
import com.kaikeba.entity.pojo.User;
import com.kaikeba.service.UserService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
import java.util.List;
/**
* @author sunyang
* @date 2021/5/31 11:32
*/
@Controller
@RequestMapping("/user")
public class UserController {@Resource
private UserService userService;
@GetMapping("/all")
public String searchAll(Model model) {
List all = userService.findAll();
model.addAttribute("users", all);
model.addAttribute("text","我这是测试th:text");
return "user";
}/**
* @desc thymeleaf测试
*
* @param model
* @return java.lang.String
* @date 2021/5/31 16:42
* @auther sunyang
*/
@GetMapping("/temp")
public String temp(Model model) {
List all = userService.findAll();
model.addAttribute("users", all);
model.addAttribute("text","我这是测试th:text");
return "temp";
}
}
6 实体类User
package com.kaikeba.entity.pojo;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.Date;
/**
* @author sunyang
* @date 2021/5/31 11:30
*/
@Table(name = "tbs_user")
public class User {
// 主键 自增
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String userName;
private String password;
private String name;
private Integer age;
private Integer sex;
private Date birthday;
private Date created;
private Date updated;
private String note;
public Integer getId() {
return id;
}public void setId(Integer id) {
this.id = id;
}public String getUserName() {
return userName;
}public void setUserName(String userName) {
this.userName = userName;
}public String getPassword() {
return password;
}public void setPassword(String password) {
this.password = password;
}public String getName() {
return name;
}public void setName(String name) {
this.name = name;
}public Integer getAge() {
return age;
}public void setAge(Integer age) {
this.age = age;
}public Integer getSex() {
return sex;
}public void setSex(Integer sex) {
this.sex = sex;
}public Date getBirthday() {
return birthday;
}public void setBirthday(Date birthday) {
this.birthday = birthday;
}public Date getCreated() {
return created;
}public void setCreated(Date created) {
this.created = created;
}public Date getUpdated() {
return updated;
}public void setUpdated(Date updated) {
this.updated = updated;
}public String getNote() {
return note;
}public void setNote(String note) {
this.note = note;
}@Override
public String toString() {
return "User{" +
"id=" + id +
", userName='" + userName + '\'' +
", password='" + password + '\'' +
", name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
", birthday=" + birthday +
", created=" + created +
", updated=" + updated +
", note='" + note + '\'' +
'}';
}
}
7 UserMapper
package com.kaikeba.mapper;
import com.kaikeba.entity.pojo.User;
import org.apache.ibatis.annotations.Mapper;
/**
* @author sunyang
* @date 2021/5/31 11:29
*/
@Mapper
public interface UserMapper extends tk.mybatis.mapper.common.Mapper {
}
8 UserService
package com.kaikeba.service;
import com.kaikeba.entity.pojo.User;
import java.util.List;
/**
* @author sunyang
* @date 2021/5/31 11:29
*/
public interface UserService {
/**
* @return java.util.List
* @desc 查询所有数据
* @date 2021/5/31 11:31
* @auther sunyang
*/
List findAll();
}
9 UserServiceImpl
package com.kaikeba.service.impl;
import com.kaikeba.entity.pojo.User;
import com.kaikeba.mapper.UserMapper;
import com.kaikeba.service.UserService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
/**
* @author sunyang
* @date 2021/5/31 11:30
*/
@Service
public class UserServiceImpl implements UserService {@Resource
private UserMapper userMapper;
@Override
public List findAll() {
return userMapper.selectAll();
}
}
四 测试结果 1 循环
文章图片
2 布局、内置对象和其他指令 【java|SpringBoot学习(三)—————— 框架整合其他框架之三(Thymeleaf)】
文章图片
内联的js:
文章图片
推荐阅读
- SpringBoot|SpringBoot——SSMP整合案例
- 微服务的学习|微服务08_RabbitMQ的SpringAMQP基本介绍
- 微服务的学习|微服务23_服务异步通信01(RabbitMQ消息可靠性)
- web开发学习|HTML期末大作业放在了阿里云服务器上
- Java|Java面试突击系列(五)(Redis集群模式)
- 面试|上周,XX保险面试,凉了!!!
- 移动开发|校友在美团 Android 岗的四面分享~
- 游戏|直播新玩法背后的音视频技术演进
- android|记录JAVA中Calendar类的一个问题