Thymeleaf是一个适用于Web和独立环境的服务器端Java模板引擎。
Thymeleaf的主要目标是让你的开发工作流程变得更简洁,更高效,可以在浏览器正确的显示HTML;它可以将你的后台数据渲染至前端页面。
与Thymeleaf同类的产品包括:Jsp、Freemarker、Beetle等。但是Thymeleaf是Spring Boot 官方推荐的,所以学习它是没错的。
- 初识Thymeleaf
可以看到用 Thymeleaf编写的HTML模板看起来和HTML一样。Thymeleaf拥有自己的标签 th:xx
<table>
<thead>
<tr>
<th th:text="#{msgs.headers.name}">Name</th>
<th th:text="#{msgs.headers.price}">Price</th>
</tr>
</thead>
<tbody>
<tr th:each="prod: ${allProducts}">
<td th:text="${prod.name}">Oranges</td>
<td th:text="${#numbers.formatDecimal(prod.price, 1, 2)}">0.99</td>
</tr>
</tbody>
</table>
通过这张图我们可以看到,数据是从后台封装好,传给前台,前台通过Thymeleaf模板引擎标签渲染到前台页面展示数据。
Spring Boot 与Thymeleaf整合
下面是整合的步骤
1.引入Thymeleaf的Jar包spring-boot-starter-thymeleaf
pom.xml内容如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.learn</groupId>
<artifactId>learn8</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>
</project>
2.配置Thymeleaf的相关属性
在application.yml中增加如下内容
spring:
# 模板引擎
thymeleaf:
mode: HTML
encoding: utf-8
# 禁用缓存
cache: false
到此我们的Spring Boot就与Thymeleaf愉快的整合好了。
我们可以看下引入的相关包,使用的模板引擎是3.0版本的,当前的最新版本
下面开启我们Thymeleaf的使用吧!
我们写一个最简单的例子,需求是:后台处理数据将数据显示在前台页面中。
创建Controller类生成数据并向前台传递
ThymeleafTestController
package org.learn.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class ThymeleafController {
@GetMapping("/ThymeleafPage")
public String ThymeleafPage(Model model){
model.addAttribute("hello","hello,thymeleaf");
return "thymeleafdemo";
}
}
- 在resources/templates目录下创建对应的html页面。
注意:Spring Boot 默认规定是将动态的模板引擎页面放至resources/templates目录下,系统会在该目录下查找对应的文件!
thymeleafdemo.html
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Thymeleaf介绍</title> </head> <body> <span th:text="${hello}"></span> </body> </html>
页面上我们做了如下的事情
1.增加<html xmlns:th="http://www.thymeleaf.org">来识别thymeleaf标签
2.输出后台的值,通过th:text="${hello}"
访问 http://localhost:8080/ThymeleafPage
页面返回的结果如下图
以上就是一个简单的Spring Boot 整合Thymeleaf的例子,简单的从后台将数据输出到前台页面当中。
下面我们介绍一些常用的thymeleaf标签
- 从本地化文件(message.properties)获取值
当我们在项目中创建了message.properties文件,并将文件中内容在页面显示时
weclome=欢迎
我们需要在页面中使用 th:text="#{weclome}" 注意是用“#”
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Thymeleaf介绍</title>
</head>
<body>
<span th:text="${hello}"></span>
<br/>
<!--#{weclome}读取message.properties中相应的属性-->
<h2 th:text="#{weclome}"></h2>
</body>
</html>
2.链接标签 - th:href标签的使用
th:href写法为th:href="@{值}"
<span >th:href标签的使用</span>
<a th:href="@{/thymeleaf/testHref}">这是一个链接</a>
该链接的地址就会是 localhost:8080/thymeleaf/testHref
当页面加载css时通过th:href引用,比如
<link th:href="@{/css/style.css}" rel="stylesheet"/>
当引用css这种静态资源时使用th:href标签,系统会默认路径是从resources/static下查找,所以我们的style.css样式是放在该目录下的,该样式的完整请求路径是localhost:8080/css/styles.css
3.src示例:th:src标签
此标签用于引入js,img等静态资源,使用方法如下
<script type="text/javascript" th:src="@{/plugins/jquery/jquery-3.2.1.min.js}"></script>
4.条件判断 th:if
Thymeleaft条件判断表达式如下:
gt:great than(大于)>
ge:great equal(大于等于)>=
eq:equal(等于)==
lt:less than(小于)<
le:less equal(小于等于)<=
ne:not equal(不等于)!=
如果personBean.age大于10 则显示该div
<div th:if="${personBean.age}gt 5">
条件成立,执行该div
</div>
5.循环 th:each
th:each属性用于迭代循环,语法:th:each="obj,iterStat:${objList}"
迭代对象可以是Java.util.List,java.util.Map,数组等;
iterStat称作状态变量,属性有:(可忽略)
index:当前迭代对象的index(从0开始计算)
count: 当前迭代对象的index(从1开始计算)
size:被迭代对象的大小
current:当前迭代变量
even/odd:布尔值,当前循环是否是偶数/奇数(从0开始计算)
first:布尔值,当前循环是否是第一个
last:布尔值,当前循环是否是最后一个
6.格式化输出(内置方法)
Thymeleaf提供了一些内置的格式化输出的标签,方便对显示的数据进行格式化处理。
- dates : java.util.Date的功能方法类。
- calendars : 类似#dates,面向java.util.Calendar
- numbers : 格式化数字的功能方法类
- strings : 字符串对象的功能类,contains,startWiths,prepending/appending等等。
- objects: 对objects的功能类操作。
- bools: 对布尔值求值的功能方法。
- arrays:对数组的功能类方法。
- lists: 对lists功能类方法
- sets
- maps
<span>格式化輸出(內置方法)</span><br/>
字符串长度:<input type="text" th:value="${#strings.length(personBean.name)}"/>
7.引用公共片段 (th:fragment,th:insert)
使用场景:
1.一些公共的页面元素,比如我们在项目中几乎每个页面都有底部的版权信息、网站相关信息的介绍,那么我们可以把这部门内容放在一个页面当中,其他页面需要引用的则直接通过th:inser标签引用该片段。
2.一些公共的静态样式和js也可以放置一个公共页面,需要调用的页面直接引用片段就可以,这样的好处是不需要在每个页面重复一些公共资源获取的代码,便于维护。
我们可以先创建一个片段,新建一个页面foot.html,内容如下
th:fragment标签用于声明一个片段。
<div th:fragment="bottom">
<div>版权信息,备案号:XXXXXX</div>
</div>
在hello.html页面引入该片段,引入片段的方式
<div th:insert="foot :: bottom"></div>
运行程序结果如下,红框的内容就是从片段中引入过来的
以下是本章节是所有讲到的标签实例代码,也可以去我的码云上下载源码,点击此处下载源码
ThymeleafController
package org.learn.controller;
import org.learn.bean.PersonBean;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.ArrayList;
import java.util.List;
@Controller
public class ThymeleafController {
@GetMapping("/ThymeleafPage")
public String ThymeleafPage(Model model){
PersonBean personBean = new PersonBean();
personBean.setName("hello");
personBean.setPassword("password");
personBean.setAddress("my address");
personBean.setAge(10);
List<PersonBean> personsList = new ArrayList<>();
personsList.add(personBean);
PersonBean personBean2 = new PersonBean();
personBean2.setName("hello2");
personBean2.setPassword("password2");
personBean2.setAddress("my address2");
personBean2.setAge(11);
personsList.add(personBean2);
PersonBean personBean3 = new PersonBean();
personBean3.setName("hello3");
personBean3.setPassword("password3");
personBean3.setAddress("my address3");
personBean3.setAge(12);
personsList.add(personBean3);
model.addAttribute("personBean",personBean); //Bean
model.addAttribute("personsList",personsList); //List
model.addAttribute("hello","hello,thymeleaf"); //String
return "thymeleafdemo";
}
}
PersonBean
package org.learn.bean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix="person")
public class PersonBean {
private String name;
private String password;
private String address;
private Integer age;
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 String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
thymeleafdemo.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Thymeleaf介绍</title>
<link th:href="@{/css/style.css}" rel="stylesheet"/>
</head>
<body>
<span th:text="${hello}"></span>
<br/>
<!--#{weclome}读取message.properties中相应的属性-->
<h2 th:text="#{weclome}"></h2>
<br/>
<br/>
<br/>
<span>th:if条件表达式</span>
<br/>
<div th:if="${personBean.age}gt 5">
条件成立,执行该div
</div>
<br/>
<br/>
<br/>
<ol>
<li>List循环:
<table border="1">
<tr>
<th>用户名</th>
<th>密碼</th>
<th>地址</th>
<th>年齡</th>
</tr>
<tr th:each="person : ${personsList}">
<td th:text="${person.name}"></td>
<td th:text="${person.password}"></td>
<td th:text="${person.address}"></td>
<th th:text="${person.age}"></th>
</tr>
</table>
</li>
</ol>
<br/>
<br/>
<br/>
<span>格式化輸出(內置方法)</span><br/>
字符串长度:<input type="text" th:value="${#strings.length(personBean.name)}"/>
<br/>
<br/>
<br/>
<span >th:href标签的使用</span>
<a th:href="@{/thymeleaf/testHref}">这是一个链接</a>
<br/>
<br/>
<br/>
引入片段信息
<div th:insert="foot :: bottom"></div>
</body>
<script type="text/javascript" th:src="@{/plugins/jquery/jquery-3.2.1.min.js}"></script>
</html>
foot.html
<div th:fragment="bottom">
<div>版权信息,备案号:XXXXXX</div>
</div>
页面输出结果: