avatar

SpringBoot1.X集成Thymeleaf

本篇介绍 SpringBoot集成模板引擎Thymeleaf以及Thymeleaf模板引擎的相关语法

1.Thymeleaf模板引擎介绍

提示:Spring Boot 推荐使用 Thymeleaf 来代替 JSP ,

Thymeleaf 是一款用于渲染 XML/XHTML/HTML 5 内容的模板引擎。类似 JSP、Velocity、FreeMaker 等,它也可以轻易的与 Spring MVC 等 Web 框架进行集成作为 Web 应用的模板引擎。与其他模板引擎相比,Thymeleaf 最大的特点是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个 Web 应用。

例如:

1
2
3
Velocity: <p>$message</p>
FreeMarker: <p>${message}</p>
Thymeleaf: <p th:text="${message}">Hello World!</p>

如果将上面三句话插入到一个静态页面,直接打开该静态页面,Velocity显示$message,FreeMarker显示${message},Thymeleaf显示 Hello World!。能够友好显示数据的只有Thymeleaf

Thymeleaf 的作用域在 html 标签内,类似标签的一个属性来使用,这就是它的特点

2.开发环境搭建

1.添加依赖

小技巧

​ net.sourceforge.nekohtml 这个依赖对于开发很有用,因为thymeleaf的语法严格要求html5语法,必须有结束标签,配置该依赖后可以忽略这些问题,该依赖要和spring.thymeleaf.mode=LEGACYHTML5这个配置一起使用

1
2
3
4
5
6
7
8
9
10
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--兼容不严谨的html5语法-->
<dependency>
<groupId>net.sourceforge.nekohtml</groupId>
<artifactId>nekohtml</artifactId>
<version>1.9.22</version>
</dependency>

2.编写页面

注意:

​ templates目录不存在,需要手动创建

​ 引入thymeleaf 的约束一定要在html标签中引入

spring-boot项目静态文件目录:/src/java/resources/static
spring-boot项目模板文件目录:/src/java/resources/templates
所以新建立的.html文件应该放在/src/java/resources/templates下。

文章这里在/src/java/resources/templates 目录下新建index.html,内容如下

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
hello world
</body>
</html>

3.修改application.properties

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#thymelea模板配置
#关闭thymeleaf缓存 开发时使用 否则没有实时画面
spring.thymeleaf.cache=false
# 构建URL时附加查看名称的后缀.
spring.thymeleaf.suffix=.html
#模板编码
spring.thymeleaf.mode=LEGACYHTML5
spring.thymeleaf.encoding=UTF-8
#Content-Type值
spring.thymeleaf.content-type=text/html
## 静态文件请求匹配方式
spring.mvc.static-path-pattern=/**
# 修改默认的静态寻址资源目录
spring.resources.static-locations = classpath:/templates/,classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/
## 检查模板是否存在,然后再呈现
spring.thymeleaf.check-template-location=true
#启用MVC Thymeleaf视图分辨率
spring.thymeleaf.enabled=true

4.创建控制器

注意:

​ 这里必须使用@Controller注解,不要使用@RestController

​ 方法返回值中的页面不能带有.html后缀

1
2
3
4
5
6
7
8
@Controller()
public class ThymeleafDemoController {
@RequestMapping("/thymeleafDemo")
public String index(ModelMap model){

return "index";//跳转到static/templates/index.html页面
}
}

5.测试

访问http://localhost:8080/thymeleafDemo

3.引入外部JS和CSS

这里以引入bootsstrap为例

##1.导入bootstrap所需相关文件

首先在resource/static目录下引入以下文件

2.在模板页面引入资源文件

语法说明

@{/js/jquery.js}相对于项目上下文(Context,亦即项目部署时的路径名)的相对路径,例如,假设部署的项目Context为 app ,则thymeleaf的写法和实际效果如下图。点击该链接时,访问的地址是http://{serverName}:{port}/app/js/jquery.js

打开resource/templates/index.html

修改head标签,在其中引入相关文件

1
2
3
4
5
6
7
8
9
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--引入bootstrap相关JS-->
<script th:src="@{/js/jquery.js}"></script>
<script th:src="@{/js/bootstrap.min.js}"></script>
<!--引入bootstrap相关样式-->
<link rel="stylesheet" th:href="@{/css/bootstrap.min.css}"></link>
</head>

3.使用bootstrap相关样式

1
2
3
4
5
6
7
8
9
<body>
<div class="container">
<div class="row">
<div class="col-md-12">
<button type="button" class="btn btn-danger">按钮</button>
</div>
</div>
</div>
</body>

4.th:模板语法

在模板语法中所有的表达式都应该用 ${表达式} 包裹起来

显示数据

1
<p th:text="${message}"></p>

循环

1
2
<tr th:each="user,userStat:${users}">
</tr>

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:布尔值,当前循环是否是最后一个

判断

1
<a th:if="${'1' == flag}" >

综合小案例

需求:在页面显示所有的姓名,隔行换色,如果是奇数行最后一个单元格则显示奇数,否则显示偶数

使用到的标签 th:text, th:if, th:each,th:class

控制器代码

1
2
3
4
5
6
7
8
9
10
11
12
@RequestMapping("/thymeleafDemo")
public String index(ModelMap model){
List<String> names = new ArrayList<String>();
names.add("风清扬");
names.add("路人甲");
names.add("东方不败");
names.add("独孤求败");
names.add("鬼脚七");
names.add("孙悟空");
model.addAttribute("names",names);
return "index";//跳转到index.html页面
}

页面代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--引入bootstrap相关JS-->
<script th:src="@{/js/jquery.js}"></script>
<script th:src="@{/js/bootstrap.min.js}"></script>
<!--引入bootstrap相关样式-->
<link rel="stylesheet" th:href="@{/css/bootstrap.min.css}"></link>

</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-12">
<table class="table ">
<tr class="warning">
<td>索引</td>
<td>序号</td>
<td>姓名</td>
<td>奇/偶</td>
</tr>
<tr th:each="name,state:${names}" th:class="${state.index%2==0?'success':'info'}">
<td th:text="${state.index}">从0开始</td>
<td th:text="${state.count}">从1开始</td>
<td th:text="${name}">姓名</td>
<td th:if="${state.index%2==0}">偶数</td>
<td th:if="${state.index%2!=0}">奇数</td>
</tr>
</table>
</div>
</div>
</div>
</body>
</html>

页面效果

附:th标签库

关键字 功能介绍 案例
th:id 替换id <input th:id="'xxx' + ${collect.id}"/>
th:text 文本替换 <p th:text="${collect.description}">description</p>
th:utext 支持html的文本替换 <p th:utext="${htmlcontent}">conten</p>
th:object 替换对象 <div th:object="${session.user}">
th:value 属性赋值 <input th:value="${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:onclick="'getCollect()'"
th:each 属性赋值 tr th:each="user,userStat:${users}">
th:if 判断条件 <a th:if="${userId == collect.userId}" >
th:href 链接地址 <a th:href="@{/login}" th:unless=${session.user != null}>Login</a> />
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="(${xxx.id} == ${configObj.dd})"
th:src 图片类地址引入 <img class="img-responsive" alt="App Logo" th:src="@{/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:删除包含标签和所有的孩子。
th:attr 设置标签属性,多个属性可以用逗号分隔 比如 th:attr="src=@{/image/aa.jpg},title=#{logo}",此标签不太优雅,一般用的比较少。
th:unless 和th:if判断相反 <a th:href="@{/login}" th:unless=${session.user != null}>Login</a>
文章作者: 微信:hao_yongliang
文章链接: https://haoyongliang.gitee.io/2018/06/08/SpringBoot/SpringBoot1.X%E9%9B%86%E6%88%90Thymeleaf/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 郝永亮的主页
打赏
  • 微信
    微信
  • 支付寶
    支付寶

评论