赞
踩
Thymeleaf 官网:https://www.thymeleaf.org/
Thymeleaf是一款用于渲染XML/XHTML/HTML5内容的模板引擎。类似JSP,Velocity,FreeMaker等。它也可以轻易的与Spring MVC等Web框架进行集成作为Web应用的模板引擎。Thymeleaf最大的特点是能够正确显示模板页面,而不需要启动整个Web应用。
Thymeleaf 模板引擎的特点:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>2.4.3</version>
</dependency>
spring:
#开始thymeleaf设置
thymeleaf:
#禁用模板缓存
cache: false
package com.offcn.demo.controller; @Controller public class FirstThymeleafController { /** * 访问http://localhost:8080/first * 将数据message填充到templates/index.html * @param model * @return */ @GetMapping("/first") public String indexPage(Model model) { String message = "Hello, Thymeleaf!"; model.addAttribute("message", message); return "index"; } }
在resources/templates下新建index.html
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<h1 th:text="${message}"></h1>
</body>
</html>
http://localhost:8080/first
Thymeleaf 作为一种模板引擎,它拥有自己的语法规则。Thymeleaf 语法分为以下 2 类:
标准表达式语法
th 属性
Thymeleaf 模板引擎支持多种表达式:
使用变量表达式可以获取对象的属性和方法。例如,获取 person 对象的 lastName 属性,表达式形式如下:
${person.lastName}
使用变量表达式还可以使用内置基本对象,获取内置对象的属性,调用内置对象的方法。Thymeleaf中常用的内置基本对象如下:
我们通过以下 2 种形式,都可以获取到 session 对象中的 map 属性:
${#session.getAttribute('map')}
${session.map}
除了能使用内置的基本对象外,变量表达式还可以使用一些内置的工具对象。
我们可以使用内置工具对象 strings 的 equals 方法,来判断字符串与对象的某个属性是否相等,代码如下。
${#strings.equals('why',name)}
选择变量表达式与变量表达式功能基本一致,只是在变量表达式的基础上增加了与 th:object 的配合使用。
当使用 th:object 存储一个对象后,我们可以在其后代中使用选择变量表达式(*{…})获取该对象中的属性,其中,“**”即代表该对象。
<div th:object="${session.user}" >
<p th:text="*{fisrtName}">firstname</p>
</div>
th:object 用于存储一个临时变量,该变量只在该标签及其后代中有效。
无论是静态资源的引用,还是 form 表单的请求,凡是链接都可以用链接表达式 (@{…})。
无参请求:
<a href="http://www.baidu.com">传统写法:跳转至百度</a><br/>
<a th:href="@{http://www.baidu.com}">路径表达式:跳转至百度</a><br/>//绝对路径
<a th:href="@{/user/detail1}">跳转至:/user/detail1</a><br/>//相对路径
有参请求:
<a href="http://localhost:8080/test?username='zhangsan'">传统写法,带参数:/test,并带参数username</a><br/>
<a th:href="@{http://localhost:8080/test?username=zhangsan}">路径表达式写法,带参数:/test,并带参数username</a><br/>//绝对路径
<a th:href="@{/test?username=lisi}">相对路径,带参数</a>//相对路径
该表达式称之为消息表达式,消息表达式主要用于从消息源中提取消息内容实现国际化。
<p th:utext="#{home.welcome}">Hello,World!</p>
片段引用表达式用于在模板页面中引用其他的模板片段。
以上语法结构说明如下:
属性 | 描述 |
---|---|
th:action | 定义后台控制器的路径,类似标签的 action 属性,主要结合 URL 表达式,获取动态变量 |
th:id | 类似 html 标签中的 id 属性 |
th:text | 文本替换,转义特殊字符 |
th:utext | 文本替换,不转义特殊字符 |
th:object | 在父标签选择对象,子标签使用 *{…} 选择表达式选取值。没有选择对象,那子标签使用选择表达式和 ${…} 变量表达式是一样的效果。 |
th:value | 替换 value 属性 |
th:name | 设置名称 |
th:src | 替换 HTML 中的 src 属性 |
th:each | 遍历,支持 Iterable、Map、数组等。 |
th:style | 设置样式 |
th:onclick | 点击事件 |
th:with | 局部变量赋值运算 |
th:if | 根据条件判断是否需要展示此标签 |
th:insert | 布局标签;将使用 th:fragment 属性指定的模板片段(包含标签)插入到当前标签中 |
th:inline | 内联属性; 该属性有 text,none,javascript 三种取值, 在 |
package com.offcn.demo.bean; public class User { private Integer id; private String name; private int age; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
package com.offcn.demo.controller; import java.util.HashMap; import java.util.Map; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import com.offcn.demo.bean.User; @Controller public class SecondThymeleafController { @GetMapping("/second") public String indexPage(Model model) { String message = "Hello, Thymeleaf!"; User u = new User(); u.setId(1); u.setName("why"); u.setAge(18); Map<String,Object> map=new HashMap<>(); map.put("src1","1.jpg"); map.put("src2","2.jpg"); model.addAttribute("message", message); model.addAttribute("user", u); model.addAttribute("src", map); return "index2"; } }
<!doctype html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>首页</title> </head> <body> <h1 th:text="${message}"></h1> <img th:src="${src.src1}"/> </br> <img th:src="${src.src2}"/> </br> <span th:text="${user.id}"></span> <span th:text="${user.name}"></span> <span th:text="${user.age}"></span> </body> </html>
package com.offcn.demo.controller; @Controller public class ThreeThymeleafController { @GetMapping("/three") public String indexPage(Model model) { List<User> list=new ArrayList<User>(); User u1 = new User(); u1.setId(1); u1.setName("张三"); u1.setAge(18); list.add(u1); User u2 = new User(); u2.setId(2); u2.setName("李四"); u2.setAge(28); list.add(u2); User u3 = new User(); u3.setId(3); u3.setName("王五"); u3.setAge(25); list.add(u3); User u4 = new User(); u4.setId(4); u4.setName("麻子"); u4.setAge(888); list.add(u4); model.addAttribute("userList", list); return "index3"; } }
<!doctype html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>首页</title> </head> <body> <table width="200" style="text-align: center;"> <tr> <th>编号</th> <th>姓名</th> <th>年龄</th> <th>index</th> </tr> <tr th:each="user,iterStat : ${userList}"> <td th:text="${user.id}"></td> <td th:text="${user.name}"></td> <td th:text="${user.age}"></td> <td th:text="${iterStat.index}">index</td> </tr> </table> </body> </html>
package com.offcn.demo.controller;
@Controller
public class FourThymeleafController {
@GetMapping("/four")
public String indexPage(Model model) {
model.addAttribute("userName", 互联网底层民工");
model.addAttribute("href", "https://blog.csdn.net/m0_67296957");
return "index4";
}
}
<!doctype html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>首页</title> </head> <body> <!-- 给标签赋值 th:text --> <h1 th:text="${userName}"></h1> <!-- 给属性赋值 th:value、th:属性名称 --> <input type="text" name="names" th:value="${userName}"/> </br> <em th:size="${userName}"></em> <!-- 字符串拼接 --> <span th:text="'欢迎来:'+${userName}+'学习!'"></span> </br> <!-- 字符串拼接,方式2 --> <span th:text="|欢迎来:${userName}学习!|"></span> </body> </html>
package com.offcn.demo.controller;
@Controller
public class FiveThymeleafController {
@GetMapping("/five")
public String indexPage(Model model) {
model.addAttribute("flag", "yes");
model.addAttribute("menu", "admin");
model.addAttribute("manager", "manager");
return "index5";
}
}
<!doctype html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>首页</title> </head> <body> <!-- th:if 条件成立就显示 --> <h1 th:if="${flag=='yes'}" >互联网底层民工</h1> <!-- th:unless 条件不成立就显示 --> <h1 th:unless="${flag=='no'}" >why</h1> <!-- switch选择语句 --> <div th:switch="${menu}"> <p th:case="'admin'">User is an administrator</p> <p th:case="${manager}">User is a manager</p> </div> </body> </html>
如果我们让IDE识别 .css文件,那么我们要用相对路径来引入这个文件。如果我们想要在发布后服务器能够加载这个文件,我们就必须用相对于resources或static的位置来引入静态文件。
显然,一般情况下我们不能兼顾这两个问题,只能要么在编写的时候用相对自己的路径,然后在发布的时候用相对于项目资源文件夹的路径,要么就只能放弃IDE的提示,非常尴尬。
而在Thymeleaf中,我们可很好的处理这一点。在引入资源的时候,我们可以写类似下面的代码:
<link rel="stylesheet" type="text/css" media="all" href="../../css/gtvg.css" th:href="@{/css/gtvg.css}" />
当我们在没有后台渲染的情况下,浏览器会认得href,但是不认得th:href,这样它就会选择以相对与本文件的相对路径去加载静态文件。而且我们的IDE也能识别这样的加载方式,从而给我们提示。
当我们在有后台渲染的情况下,后台会把这个标签渲染为这样:
<link rel="stylesheet" type="text/css" media="all" href="/css/gtvg.css" />
原来的href标签会被替换成相对于项目的路径,因此服务器就能找到正确的资源,从而正确渲染。
fragment类似于JSP的tag,在html中文件中,可以将多个地方出现的元素块用fragment包起来使用。
**定义fragment,**所有的fragment可以写在一个文件里面,也可以单独存在,例如:
<body>
<h1 th:fragment="copy">
© 1999-2022 Offcn.All Rights Reserved
</h1>
</body>
注意: 在Springboot中,默认读取thymeleaf文件的路径是:src/main/resource/templates
package com.offcn.demo.controller;
@Controller
public class SixThymeleafController {
@GetMapping("/six")
public String indexPage(Model model) {
return "index6";
}
}
<!doctype html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>首页</title> </head> <body> <!-- 把片段的内容插入到当前位置 --> <div style="color: #82ff6c" th:insert="~{footer :: copy}"></div> </br> <!-- 使用片段的内容替换当前标签 --> <div style="color: #82ff6c" th:replace="~{footer :: copy}"></div> </br> <!-- 保留自己的主标签,不要片段的主标签 --> <div style="color: #82ff6c" th:include="~{footer :: copy}"></div> </body> </html>
th:insert:保留自己的主标签,保留th:fragment的主标签。
th:replace:不要自己的主标签,保留th:fragment的主标签。
th:include:保留自己的主标签,不要th:fragment的主标签。
#dates:与java.util.Data对象的方法对应,格式化、日期组件抽取等等
#numbers:格式化数字对象的工具方法
#strings:与java.lang.String对应的工具方法
package com.offcn.demo.controller; @Controller public class SevenThymeleafController { @GetMapping("/seven") public String indexPage(Model model) { //日期时间 Date date = new Date(); model.addAttribute("date", date); //小数的金额 double price=128.5678D; model.addAttribute("price", price); //定义大文本数据 String str="Thymeleaf是Web和独立环境的现代服务器端Java模板引擎,能够处理HTML,XML,JavaScript,CSS甚至纯文本。\r\n" + "Thymeleaf的主要目标是提供一种优雅和高度可维护的创建模板的方式。为了实现这一点,它建立在自然模板的概念上,将其逻辑注入到模板文件中,不会影响模板被用作设计原型。这改善了设计的沟通,弥补了设计和开发团队之间的差距。\r\n" + "Thymeleaf也从一开始就设计了Web标准 - 特别是HTML5 - 允许您创建完全验证的模板,如果这是您需要的\r\n" ; model.addAttribute("strText", str); //定义字符串 String str2="JAVA-why"; model.addAttribute("str2", str2); return "index7"; } }
<!doctype html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>首页</title> </head> <body> 时间:<span th:text="${#dates.format(date,'yyyy-MM-dd HH:mm:ss')}">4564546</span> </br> 金额:<span th:text="'¥'+${#numbers.formatDecimal(price, 1, 2)}">180</span> </br> <!-- # 这里的含义是 如果 atc.text 这个变量多余60个字符,后面显示... --> <p th:text="${#strings.abbreviate(strText,60)}">内容内容内容</p> <!-- 判断字符串是否为空 --> <span th:if="${!#strings.isEmpty(str2)}">字符串str2不为空</span></br> <!-- 截取字符串,指定长度 --> <span th:text="${#strings.substring(str2,0,4)}">字符串str2的值</span> </body> </html>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。