thymeleaf模板手动渲染
首先编写一个mail.html页面:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>hello,欢迎<span th:text="${username}"></span> 加入xxx公司!您的入职如下:</p>
<table border="1">
<tr>
<td>职位</td>
<td th:text="${position}"></td>
</tr>
<tr>
<td>薪水</td>
<td th:text="${slaray}"></td>
</tr>
</table>
</body>
</html>
然后我们编写测试类:
@Autowired
TemplateEngine templateEngine;
@Test
void contextLoads() {
Context context = new Context();
context.setVariable("username","LQZ_DJY");
context.setVariable("position","java工程师");
context.setVariable("slaray","30000");
String mail = templateEngine.process("mail", context);
System.out.println(mail);
}
最后我们就可以得到自己渲染完成的页面并将它打印出来:
thymeleaf简单表达式
Case1:
<div th:text="${user.name}"></div>
<div th:text="${user.password}"></div>
<div th:text="*{user.name}"></div>
<div th:text="*{user.password}"></div>
测试发现两个表达式作用都一样
Case2:
同样表达式*和$还有以下用法:
<div th:object="${user}">
<div th:text="*{name}"></div>
<div th:text="*{password}"></div>
</div>
结果就跟上面结果相同
Case3:
hello=hello
hello=你好
<div th:text="#{hello}"></div>
国际化配置,当浏览器切换到中文环境就会显示“你好”,切换到英文环境就会显示hello
Case4:
<head>
<meta charset="UTF-8">
<title>Title</title>
<script th:src="@{http://localhost:8080/hello.js}"></script>
//引用相对路径
<script th:src="@{~/hello.js}"></script>
<script th:src="@{//localhost:8080/hello.js}"></script>
//加入参数
<script th:src="@{http://localhost:8080/hello.js(name='dong',passwor=123)}"></script>
</head>
结果可以得到:
Case5:
加入引用上下文:
server.servlet.context-path=/dong
我们继续访问,发现js文件不能正确加载 加入下面的语句就可以解决:
<script th:src="@{/hello.js}"></script>
各种表达式
字面量
- 文本字面量:‘one text’, ‘Another one!’,…
- 数字字面量:0, 34, 3.0, 12.3,…
- 布尔字面量:true, false
- Null字面量:null
- 字面量标记:one, sometext, main,…
<div th:text="'这是 文本字面量(有空格)'"></div>
<div th:text="dong"></div>
<div th:text="99"></div>
<div th:text="true"></div>
文本运算
文本可以使用 + 进行拼接
<div th:text="'hello '+'dong'"></div>
<div th:text="'hello '+${user.username}"></div>
如果字符串中包含变量,也可以使用另一种简单的方式,叫做字面量置换,用 | 代替 ‘…’ + ‘…’,如下:
<div th:text="|hello ${user.username}|"></div>
<div th:text="'hello '+${user.username}+' '+|hello ${user.address}|"></div>
算术运算
算术运算有:+, -, *, / 和 %
<div th:with="number=(99*99/99+99-1)">
<div th:text="${number}"></div>
</div>
th:with 定义了一个局部变量 number,在其所在的 div 中可以使用该局部变量
布尔运算
- 二元运算符:and, or
- 布尔非(一元运算符):!, not
<div th:with="number=(99*99/99+99-1)">
<div th:text="9 eq 9 or 8 ne 8"></div>
<div th:text="!(9 eq 9 or 8 ne 8)"></div>
<div th:text="not(9 eq 9 or 8 ne 8)"></div>
</div>
比较和相等
表达式里的值可以使用 >, <, >= 和 <= 符号比较。== 和 != 运算符用于检查相等(或者不相等)。注意 XML规定 < 和 > 标签不能用于属性值,所以应当把它们转义为 < ;和 > ;
如果不想转义,也可以使用别名:gt (>);lt (<);ge (>=);le (<=);not (!)还有 eq (==), neq/ne (!=)
<div th:with="age=(99*99/99+99-1)">
<div th:text="${age} eq 197"></div>
<div th:text="${age} ne 197"></div>
<div th:text="${age} ge 197"></div>
<div th:text="${age} gt 197"></div>
<div th:text="${age} le 197"></div>
<div th:text="${age} lt 197"></div>
</div>
条件运算符
类似于我们 Java 中的三目运算符
<div th:with="age=(99*99/99+99-1)">
<div th:text="(${age} ne 197)?'yes':'no'"></div>
</div>
其中,: 后面的部分可以省略,如果省略了,又同时计算结果为 false 时,将返回 null
内置对象
基本内置对象:
- #ctx:上下文对象。
- #vars: 上下文变量。
- #locale:上下文区域设置。
- #request:(仅在 Web 上下文中)HttpServletRequest 对象。
- #response:(仅在 Web 上下文中)HttpServletResponse 对象。
- #session:(仅在 Web 上下文中)HttpSession 对象。
- #servletContext:(仅在 Web 上下文中)ServletContext 对象。
在页面可以访问到上面这些内置对象,举个简单例子:
<div th:text='${#session.getAttribute("name")}'></div>
实用内置对象:
- #execInfo:有关正在处理的模板的信息。
- #messages:在变量表达式中获取外部化消息的方法,与使用#{…}语法获得的方式相同。
- #uris:转义URL / URI部分的方法
- #conversions:执行配置的转换服务(如果有)的方法。
- #dates:java.util.Date对象的方法:格式化,组件提取等
- #calendars:类似于#dates但是java.util.Calendar对象。
- #numbers:用于格式化数字对象的方法。
- #strings:String对象的方法:contains,startsWith,prepending / appending等
- #objects:一般对象的方法。
- #bools:布尔评估的方法。
- #arrays:数组方法。
- #lists:列表的方法。
- #sets:集合的方法。
- #maps:地图方法。
- #aggregates:在数组或集合上创建聚合的方法。
- #ids:处理可能重复的id属性的方法(例如,作为迭代的结果)。
这是一些内置对象以及工具方法,使用方式也都比较容易,如果使用的是 IntelliJ IDEA,都会自动提示对象中的方法,很方便
<div th:text="${#execInfo.getProcessedTemplateName()}"></div>
<div th:text="${#arrays.length(#request.getAttribute('names'))}"></div>
设置属性值
这个是给 HTML 元素设置属性值。可以一次设置多个,多个之间用 , 分隔开
例如:
<img th:attr="src=@{/1.png},title=${user.username},alt=${user.username}">
会被渲染成:
<img src="/myapp/1.png" title="dong" alt="dong">
Thymeleaf 还支持在每一个原生的 HTML 属性前加上 th: 前缀的方式来使用动态值,像下面这样:
<img th:src="@{/1.png}" th:alt="${user.username}" th:title="${user.username}">
上面案例中的 alt 和 title 则是两个特殊的属性,可以一次性设置,像下面这样:
<img th:src="@{/1.png}" th:alt-title="${user.username}">
遍历
数组/集合/Map/Enumeration/Iterator 等的遍历也算是一个非常常见的需求,Thymeleaf 中通过 th:each 来实现遍历,像下面这样:
<table border="1">
<tr th:each="u : ${users}">
<td th:text="${u.username}"></td>
<td th:text="${u.address}"></td>
</tr>
</table>
Thymeleaf 也对此提供了支持:
- index:当前的遍历索引,从0开始。
- count:当前的遍历索引,从1开始。
- size:被遍历变量里的元素数量。
- current:每次遍历的遍历变量。
- even/odd:当前的遍历是偶数次还是奇数次。
- first:当前是否为首次遍历。
- last:当前是否为最后一次遍历。
<table border="1">
<tr th:each="u,s:${users}">
<td th:text="${u.name}"></td>
<td th:text="${u.password}"></td>
<td th:text="${s.index}"></td>
<td th:text="${s.count}"></td>
<td th:text="${s.current}"></td>
<td th:text="${s.size}"></td>
<td th:text="${s.odd}"></td>
<td th:text="${s.even}"></td>
<td th:text="${s.first}"></td>
<td th:text="${s.last}"></td>
</tr>
</table>
分支语句
只显示奇数次的遍历,可以使用 th:if,如下:
<table border="1">
<tr th:each="u,s:${users}" th:if="${s.odd}">
<td th:text="${u.name}"></td>
<td th:text="${u.password}"></td>
<td th:text="${s.index}"></td>
<td th:text="${s.count}"></td>
<td th:text="${s.current}"></td>
<td th:text="${s.size}"></td>
<td th:text="${s.odd}"></td>
<td th:text="${s.even}"></td>
<td th:text="${s.first}"></td>
<td th:text="${s.last}"></td>
</tr>
</table>
th:if 不仅仅只接受布尔值,也接受其他类型的值,例如如下值都会判定为 true:
- 值是布尔值,并且为 true
- 值是数字,并且不为 0
- 值是字符,并且不为 0
- 值是字符串,并且不为 “false”, “off” 或者 “no”
- 值不是布尔值,数字,字符或者字符串
但是值为 null,th:if 会求值为 false
th:unless 的判定条件则与 th:if 完全相反
当可能性比较多的时候,也可以使用 switch:
<table border="1">
<tr th:each="u,s:${users}" th:if="${s.odd}">
<td th:text="${u.name}"></td>
<td th:text="${u.password}"></td>
<td th:text="${s.index}"></td>
<td th:text="${s.count}"></td>
<td th:text="${s.current}"></td>
<td th:text="${s.size}"></td>
<td th:text="${s.odd}"></td>
<td th:text="${s.even}"></td>
<td th:text="${s.first}"></td>
<td th:text="${s.last}"></td>
<td th:switch="${s.odd}">
<span th:case="true">odd</span>
<span th:case="*">even</span>
</td>
</tr>
</table>
th:case="*" 则表示默认选项
本地变量
使用 th:with 可以定义一个本地变量
内联
我们可以使用属性将数据放入页面模版中,但是很多时候,内联的方式看起来更加直观一些,像下面这样:
<div>hello [[${user.username}]]</div>
用内联的方式去做拼接也显得更加自然。
[[…]] 对应于 th:text (结果会是转义的 HTML),[(…)]对应于 th:utext,它不会执行任何的 HTML 转义。
像下面这样:
<div th:with="str='hello <strong>dong</strong>'">
<div>[[${str}]]</div>
<div>[(${str})]</div>
</div>
最终的显示效果如下: 不过内联方式有一个问题。我们使用 Thymeleaf 的一大优势在于不用动态渲染就可以直接在浏览器中看到显示效果,当我们使用属性配置的时候确实是这样,但是如果我们使用内联的方式,各种表达式就会直接展示在静态网页中
也可以在 js 或者 css 中使用内联,以 js 为例,使用方式如下:
<script th:inline="javascript">
var username=[[${user.username}]]
console.log(username)
</script>
js 中需要通过 th:inline=“javascript” 开启内联
|