This blog post focuses on three aspects, namely:
- Using thymeleaf in SpringBoot
- Customize thymeleaf tool class to export static web pages
- thymeleaf commonly used tags
1. Using thymeleaf in SpringBoot
pom.xml
<!--Thymeleaf 启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
application.yml
server:
port: 8070
spring:
mvc:
static-path-pattern: /static/**
thymeleaf:
#去除thymeleaf的html严格校验
mode: LEGACYHTML5
#设定thymeleaf文件路径,默认为src/main/resources/templates
prefix: classpath:/templates/
#是否开启模板缓存,默认true,建议在开发时关闭缓存,不然没法看到实时页面,也就是修改了html后不用重启,刷新页面就能看到效果,修改完html后一定要ctrl+f9重新build一下。
cache: false
#模板编码
encoding: UTF-8
EntityDept
package demo.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Dept {
private Integer id;
private String deptName;
private String location;
}
thymeleaf template: deptList.html
Create the thymeleaf template file deptList.html in the resources/templates folder
NOTE: Use xmlns namespace
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Hello Thymeleaf</title>
</head>
<body>
<div>
<span>访问列表</span>
<table>
<thead>
<tr>
<th>部门编号</th>
<th>部门名称</th>
<th>部门地址</th>
</tr>
</thead>
<tbody>
<!--/*@thymesVar id="depts" type=""*/-->
<tr th:each="dept : ${depts}">
<td th:text="${dept.id}"></td>
<td th:text="${dept.deptName}"></td>
<td th:text="${dept.location}"></td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
Rendering data in controller
package demo;
import demo.entity.Dept;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.ArrayList;
import java.util.List;
@SpringBootApplication
@Controller
public class Demo {
public static void main(String[] args) {
SpringApplication.run(Demo.class);
}
@RequestMapping("/list")
public String gen(ModelMap modelMap){
List<Dept> depts = new ArrayList<>();
depts.add(new Dept(10, "ACCOUNTING", "NEWYORK"));
depts.add(new Dept(20, "RESEARCH", "DALLAS"));
depts.add(new Dept(30, "SALES", "CHICAGO"));
depts.add(new Dept(40, "OPERATIONS", "BOSTON"));
modelMap.addAttribute("depts", depts);
return "deptList";
}
}
When the browser requests the list path, it will jump to the templates/deptList.html page (the prefix is configured through application.yml). The effect is as shown below. You can see that the data has been successfully rendered to the HTML page.
2. Export static HTML page
Continuing the above case, add a tool class for thymeleaf to export static pages.
Utility classThymeleafUtil.java
package demo.utils;
import org.springframework.stereotype.Component;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import javax.annotation.Resource;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
@Component
public class ThymeleafUtil {
@Resource
private TemplateEngine templateEngine;
/**
* 生成静态页面
*
* @param templateName 放在根路径templates下的的模板文件的名称
* @param dest 带路径的目标文件
* @param data 数据
* @param key 模板中的key
* @return 成功返回true,失败返回false
*/
public boolean genPage(String templateName, String dest, Object data, String key) {
// 创建上下文,
Context context = new Context();
// 把数据加入上下文
Map<String, Object> vars = new HashMap<>();
vars.put(key, data);
context.setVariables(vars);
// 创建输出流,关联到一个临时文件
File destFile = new File(dest);
// 备份原页面文件
try (PrintWriter writer = new PrintWriter(destFile, "UTF-8")) {
// 利用thymeleaf模板引擎生成 静态页面
templateEngine.process(templateName, context, writer);
return true;
} catch (FileNotFoundException | UnsupportedEncodingException e) {
e.printStackTrace();
return false;
}
}
}
Create unit tests to export static pages
package demo;
import demo.entity.Dept;
import demo.utils.ThymeleafUtil;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.ArrayList;
import java.util.List;
@SpringBootTest(classes = {
Demo.class})
public class JTest {
@Autowired
private ThymeleafUtil thymeleafUtil;
/**
* 使用thymeleaf工具类生成静态文件
*/
@Test
public void testGen(){
List<Dept> depts = new ArrayList<>();
depts.add(new Dept(10, "ACCOUNTING", "NEWYORK"));
depts.add(new Dept(20, "RESEARCH", "DALLAS"));
depts.add(new Dept(30, "SALES", "CHICAGO"));
depts.add(new Dept(40, "OPERATIONS", "BOSTON"));
boolean res = thymeleafUtil.genPage("deptList", "asdf1234.html", depts, "depts");
System.out.println(res ? "ok" : "error");
}
}
After running, you can see that asdf1234.html has been exported from the project root directory.
Open this html file and find that the data has been successfully rendered.
3. Commonly used th tags
This part is referenced from:Thymeleaf’s simple syntax and commonly used th tags
Common tags for th
Keywords | Features | Case |
---|---|---|
th:id | replace id | <input th:id="'xxx' + ${collect.id}"/> |
th:text | text replacement | <p th:text="${collect.description}">description</p> |
th:utext | Support html text replacement | <p th:utext="${htmlcontent}">conten</p> |
th:object | Replace object | <div th:object="${session.user}"> |
th:value | Property assignment | <input th:value="${user.name}" /> |
th:with | Variable assignment operation | <div th:with="isEven=${prodStat.count}%2==0"></div> |
th:style | Set style | th:style="'display:' + @{(${sitrue} ? 'none' : 'inline-block')} + ''" |
th:onclick | click event | th:onclick="'getCollect()'" |
th:each | Property assignment | tr th:each="user,userStat:${users}"> |
th:if | Analyzing conditions | <a th:if="${userId == collect.userId}" > |
th:unless | Contrary to th:if judgment | <a th:href="@{/login}" th:unless=${session.user != null}>Login</a> |
th:href | link address | <a th:href="@{/login}" th:unless=${session.user != null}>Login</a> /> |
th:switch | Multiple selection used with th:case | <div th:switch="${user.role}"> |
th:case | A branch of th:switch | <p th:case="'admin'">User is an administrator</p> |
th:fragment | Layout tag defines a code snippet for easy reference in other places | <div th:fragment="alert"> |
th:include | Layout tags, replacing content into imported files | <head th:include="layout :: htmlhead" th:with="title='xx'"></head> /> |
th:replace | Layout tags, replacing the entire tag to the imported file | <div th:replace="fragments/header :: title"></div> |
th:selected | selected selection box selected | th:selected="(${xxx.id} == ${configObj.dd})" |
th: src | Image address introduction | <img class="img-responsive" alt="App Logo" th:src="@{/img/logo.png}" /> |
th:inline | You can use variables to define js scripts | <script type="text/javascript" th:inline="javascript"> |
th:action | Address for form submission | <form action="subscribe.html" th:action="@{/subscribe}"> |
th:remove | Delete an attribute | |
th:attr | Set label attributes, multiple attributes can be separated by commas | For example th:attr="src=@{/image/aa.jpg},title=#{logo}" , this tag is not very elegant and is generally used less. |