大家好,我是 bigsai,今天我们来学习 Thymeleaf,如果你对 Thymeleaf 比较陌生也不要紧,它很容易学习与理解,并有着自己鲜明的特色。
开始之前,我们依旧问一个问题:什么是 Thymeleaf?
Java模板引擎
模板引擎?你可能第一次听说模板引擎,估计你会禁不住想问:什么是模板引擎?
模板引擎
,最重要的就是模板二字,这个意思就是做好一个模板后套入对应位置的数据,最终以 html 的格式展示出来,这就是模板引擎的作用。
不仅如此,在 Java 中模板引擎还有很多,模板引擎是动态网页发展进步的产物,在最初并且流传度最广的 jsp
它就是一个模板引擎。jsp 是官方标准的模板,但是由于 jsp 的缺点比较多也挺严重的,所以很多人弃用 jsp 选用第三方的模板引擎,市面上开源的第三方的模板引擎也比较多,有 Thymeleaf、FreeMaker、Velocity 等模板引擎受众较广。
听完了模板引擎的介绍,相信你也很容易明白了模板引擎在 web 领域的主要作用:让网站实现界面和数据分离,这样大大提高了开发效率,让代码重用更加容易。
上面知晓了模板引擎的概念和功能,你也知道 Thymeleaf 是众多模板引擎的一种,你一定会好奇想深入学习 Thymeleaf 的方方面面。从官方的介绍来看,Thymeleaf 的目标很明确:
并且随着市场使用的验证 Thymeleaf 也达到的它的目标和大家对他的期望,在实际开发有着广泛的应用。Thymeleaf 作为被 Springboot 官方推荐的模板引擎,一定有很多过人和不寻同之处:
此外,Thymeleaf 在曾经还有一次大的版本升级,从 Thymeleaf2.0—>Thymeleaf3.0。在 Thymeleaf2.0 时代,Thymeleaf 基于 xml 实现,虽然它带来了许多出色强大的功能,但有时会降低性能效率,那个时候 Thymeleaf 的性能真的太差而被很多人所吐槽带来了很不好的印象。
但是 Thymeleaf3.0 对比 Thymeleaf2.0 有着翻天覆地的变化,几乎是全部重写了整个 Thymeleaf 引擎,在性能、效率上相比 Thymeleaf2 有了很大改善,能够满足更多项目的需求,且 Thymeleaf3.0 不再基于 xml 所以在 html 环境下有着更宽松的编程环境。
此外,Thymelaf3.0 在方言、独立于 Java Servlet API、重构核心 API、片段表达等方面有着巨大提升和改善,具体可以参看 Thymeleaf3 十分钟参考指南。
Thymeleaf 模板的运行离不开 web 的环境,所以你需要对相关知识学习理解才能更好的有助于你对 Thymeleaf 的学习和认知。
相信你对 Springboot 都很熟悉,我们使用 Thymeleaf 大多情况都是基于 Springboot 平台的,并且 Thymeleaf 的发展推广也离不开 Springboot 官方得支持,且本文的实战部分也是基于 Springboot 平台。
而 Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Spring Boot 致力于在蓬勃发展的快速应用开发领域 (rapid application development) 成为领导者。
简而言之,Springboot 是当前 web 开发主流,且其简化了 Spring 的配置让开发者能够更容易上手 Web 项目的开发。且 Thymeleaf 能够快速整合入 Springboot,使用方便快捷。
我们使用的 Thymeleaf 模板引擎在整个 web 项目中起到的作用为视图展示 (view),谈到视图就不得不提起模型 (model) 以及控制器 (view), 其三者在 web 项目中分工和职责不同,但又相互有联系。三者组成当今 web 项目较为流行的 MVC 架构。
MVC 全名是 Model View Controller,是模型 (model)-视图 (view)-控制器 (controller) 的缩写,其中:
使用 MVC 设计模式程序有很多优点,比如降低程序耦合、增加代码的复用性、降低开发程序和接口的成本,并且通过这样分层结构在部署维护能够提供更大的便捷性。
在 Java web 体系最流行的 MVC 框架无疑就是 Springmvc 框架了,在项目中经常配合模板引擎使用或者提供 Restful 接口。在下面案例 Thymeleaf 同样使用 Springmvc 作为 MVC 框架进行控制。
你可能还是不明白什么才是真正的动静分离,其实这个主要是由于 Thymeleaf 模板基于 html,后缀也是 .html
,所以这样就会产生一些有趣的灵魂。
对于传统 jsp 或者其他模板来说,没有一个模板引擎的后缀为 .html
,就拿 jsp 来说 jsp 的后缀为 .jsp
, 它的本质就是将一个 html 文件修改后缀为 .jsp
,然后在这个文件中增加自己的语法、标签然后执行时候通过后台处理这个文件最终返回一个 html 页面。
浏览器无法直接识别 .jsp
文件,需要借助网络 (服务端) 才能进行访问;而 Thymeleaf 用 html 做模板可以直接在浏览器中打开。开发者充分考虑 html 页面特性,将 Thymeleaf 的语法通过 html 的标签属性来定义完成,这些标签属性不会影响 html 页面的完整性和显示。如果通过后台服务端访问页面服务端会寻找这些标签将服务端对应的数据替换到相应位置实现动态页面!大体区别可以参照下图:
上图的意思就是如果直接打开这个 html 那么浏览器会对 th
等标签忽视而显示原始的内容。如果通过服务端访问那么服务端将先寻找 th
标签将服务端储存的数据替换到对应位置。具体效果可以参照下图,下图即为一个动静结合的实例。
动态页面每次修改打开都需要重新启动程序、输入链接,这个过程其实是相对漫长的。如果界面设计人员用这种方式进行页面设计时间成本高并且很麻烦,可通过静态页面设计样式,设计完成通过服务端访问即可达成目标 UI 的界面和应用,达到动静分离的效果。这个特点和优势是所有模板引擎中 Thymeleaf 所独有的!
上面既然简单介绍了 Thymeleaf, 下面咱们着手实战第一个 Thymeleaf 程序。考虑到 Thymeleaf 被 Springboot 官方推荐,并且 Springboot 已成为 javaweb 领域必不可少的技术点,咱们就用 IDEA 基于 Springboot 构建第一个 Thymeleaf 程序。Thymeleaf 提供了一组 Spring 集成,使您可以将其用作 Spring MVC 应用程序中 JSP 的全功能替代品。对于构建一个完整程序,创建第一个 Thymeleaf 程序需要以下几个步骤:
首先,打开你的 IDEA 创建新项目,选择 Spring Initializr 方式创建 Springboot 项目 ,然后点击 next。具体如下图所示。
点击 next 之后,我们进行 next 填写好 Group (一般 com 或者 com.xxx) 和 Aritifact (一般项目名) 创建。其他地方没有特殊情况不需要修改,具体如下图:
IDEA 的编译器做的很友好,可以直接选择热门的依赖而不需要去进行寻找,我们勾选其中 Web 模块的 Spring web 依赖以及 Template 模块的 Thymeleaf 依赖。finish 即可:
当然,如果你创建项目时没有勾选依赖也不要紧,在 pom.xml 中添加以下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
就这样,程序创建完毕,依赖也成功添加,你就可以在此基础上正式开始你的个性化操作。
在编写 Controller 和 Thymeleaf 之前,先让你看一下最终项目的目录结构,有个初略的印象和概念:
在其中:
项目基于 Springboot 框架,且选了 Spring web (Springmvc) 作为 mvc 框架,其中 Thymeleaf 就是 v (view) 视图层,我们需要在 controller 中指定 Thymeleaf 页面的 url,然后再 Model 中绑定数据。
我们在 com.Thymeleaf 文件下创建 controller 文件夹,在其中创建 urlController.java 的 controller 文件,文件内容 (代码) 为:
package com.Thymeleaf.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class urlController {
@GetMapping("index")//页面的url地址
public String getindex(Model model)//对应函数
{
model.addAttribute("name","bigsai");
return "index";//与templates中index.html对应
}
}
上述代码就是一个完整的 controller。部分含义如下:
返回字符串.html
)。咱们在项目的 resources 目录下的 templates 文件夹下面创建一个叫 index.html 的文件,咱们在这个 html 文件中的 <html>
标签修改为 <html xmlns:th="http://www.thymeleaf.org">
这样在 Thymeleaf 中就可以使用 Thymeleaf 的语法和规范啦。
对于第一个 Thymelaf 程序,你只需将 index.html 文件改成这样即可:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>title</title>
</head>
<body>
hello 第一个Thymeleaf程序
<div th:text="${name}">name是bigsai(我是离线数据)</div>
</body>
</html>
你可能会对 <div th:text="
这样写好之后咱们执行这个 Springboot 程序。通过网络访问 http://localhost:8080/index
上图左侧为直接打开的静态页面,而右侧是通过网络访问服务端返回的动态界面,可以看的到,界面的内容和我们预期一致,左右两侧也正是静动态页面的两个代表。
通过以上的步骤,你就完成了第一个 Thymeleaf 程序并且能够成功运行。入门便悄然开始!
上面虽然完成了第一个 Thymeleaf 程序,但是那样远远满足不了我们在项目中使用 Thymeleaf,所以我们要对 Thymeleaf 的语法规则进行更详细的学习。
虽然 Springboot 官方对 Thymeleaf 做了很多默认配置,但咱们引入 Thymeleaf 的 jar 包依赖后很可能根据自己特定需求进行更细化的配置,例如页面缓存、字体格式设置等等。
Springboot 官方提供的配置内容有以下:
# THYMELEAF (ThymeleafAutoConfiguration)
spring.thymeleaf.cache=true # Whether to enable template caching.
spring.thymeleaf.check-template=true # Whether to check that the template exists before rendering it.
spring.thymeleaf.check-template-location=true # Whether to check that the templates location exists.
spring.thymeleaf.enabled=true # Whether to enable Thymeleaf view resolution for Web frameworks.
spring.thymeleaf.enable-spring-el-compiler=false # Enable the SpringEL compiler in SpringEL expressions.
spring.thymeleaf.encoding=UTF-8 # Template files encoding.
spring.thymeleaf.excluded-view-names= # Comma-separated list of view names (patterns allowed) that should be excluded from resolution.
spring.thymeleaf.mode=HTML # Template mode to be applied to templates. See also Thymeleaf's TemplateMode enum.
spring.thymeleaf.prefix=classpath:/templates/ # Prefix that gets prepended to view names when building a URL.
spring.thymeleaf.reactive.chunked-mode-view-names= # Comma-separated list of view names (patterns allowed) that should be the only ones executed in CHUNKED mode when a max chunk size is set.
spring.thymeleaf.reactive.full-mode-view-names= # Comma-separated list of view names (patterns allowed) that should be executed in FULL mode even if a max chunk size is set.
spring.thymeleaf.reactive.max-chunk-size=0 # Maximum size of data buffers used for writing to the response, in bytes.
spring.thymeleaf.reactive.media-types= # Media types supported by the view technology.
spring.thymeleaf.servlet.content-type=text/html # Content-Type value written to HTTP responses.
spring.thymeleaf.suffix=.html # Suffix that gets appended to view names when building a URL.
spring.thymeleaf.template-resolver-order= # Order of the template resolver in the chain.
spring.thymeleaf.view-names= # Comma-separated list of view names (patterns allowed) that can be resolved.
上面的配置有些我们可能不常使用,因为 Springboot 官方做了默认配置大部分能够满足我们的使用需求,但如果你的项目有特殊需求也需要妥善使用这些配置。
比如 spring.thymeleaf.cache=false
是否允许页面缓存的配置,我们在开发时候要确保页面是最新的所以需要禁用缓存;而在上线运营时可能页面不常改动为了减少服务端压力以及提升客户端响应速度会允许页面缓存的使用。
再比如在开发虽然我们大部分使用 UTF-8 多一些,我们可以使用 spring.thymeleaf.encoding=UTF-8
来确定页面的编码,但如果你的项目是 GBK 编码就需要将它改成 GBK。
另外 Springboot 默认模板引擎文件是放在 templates 目录下: spring.thymeleaf.prefix=classpath:/templates/
, 如果你有需求将模板引擎也可修改配置,将 templates 改为自己需要的目录。同理其他的配置如果需要自定义化也可参照上面配置进行修改。
咱们上面知道 Thymeleaf 通过特殊的标签来寻找属于 Thymeleaf 的部分,并渲染该部分内容,而除了上面展示过的 th:text
之外还有很多常用标签,并且 Thymeleaf 也主要通过标签来识别替换对应位置内容,Thymeleaf 标签有很多很多,功能也很丰富,这里列举一些比较常用的标签如下:
标签 | 作用 | 示例 |
---|---|---|
th:id | 替换 id | <input th:id="${user.id}"/> |
th:text | 文本替换 | <p text:="${user.name}">bigsai</p> |
th:utext | 支持 html 的文本替换 | <p utext:="${htmlcontent}">content</p> |
th:object | 替换对象 | <div th:object="${user}"></div> |
th:value | 替换值 | <input th:value="${user.name}" > |
th:each | 迭代 | <tr th:each="student:${user}" > |
th:href | 替换超链接 | <a th:href="@{index.html}">超链接</a> |
th:src | 替换资源 | <script type="text/javascript" th:src="@{index.js}"></script> |
上面我们已经学习到 Thymeleaf 是一个基于 html 的模板引擎,但是我们还是需要加入特定标签来声明和使用 Thymeleaf 的语法。我们需要在 Thymeleaf 的头部加 Thymeleaf 标识:
<html xmlns:th="http://www.thymeleaf.org">
在 Thymeleaf 中,如果想引入链接比如 link,href,src,需要使用 @{资源地址}
引入资源。其中资源地址可以 static 目录下的静态资源,也可以是互联网中的绝对资源。
引入 css
<link rel="stylesheet" th:href="@{index.css}">
引入 JavaScript:
<script type="text/javascript" th:src="@{index.js}"></script>
超链接:
<a th:href="@{index.html}">超链接</a>
这样启动程序访问页面,页面的内容就自动修改成标准 html 语法格式的内容:
在 Thymeleaf 中可以通过 ${…} 进行取值,这点和 ONGL 表达式语法一致。 例如咱们创建这么一个对象:
public class user {
private String name;
private int age;
private String detail;
public user(String name, int age, String detail) {
this.name = name;
this.age = age;
this.detail = detail;
}
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;
}
public String getDetail() {
return detail;
}
public void setDetail(String detail) {
this.detail = detail;
}
咱们为了测试先在 Model 中添一些数据:
@GetMapping("index")//页面的url地址
public String getindex(Model model)//对应函数
{
user user1=new user("bigsai",22,"一个幽默且热爱java的社会青年");
List<String>userList=new ArrayList<>();
userList.add("zhang san 66");
userList.add("li si 66");
userList.add("wang wu 66");
Map<String ,String>map=new HashMap<>();
map.put("place","博学谷");
map.put("feeling","very well");
//数据添加到model中
model.addAttribute("name","bigsai");//普通字符串
model.addAttribute("user",user1);//储存javabean
model.addAttribute("userlist",userList);//储存List
model.addAttribute("map",map);//储存Map
return "index";//与templates中index.html对应
}
取普通字符串:
如果在 controller 中的 Model 直接存储某字符串,我们可以直接 ${对象名}
进行取值。完整代码如下:
<h2>普通字符串</h2>
<table border="0">
<tr>
<td th:text="'我的名字是:'+${name}"></td>
</tr>
</table>
运行结果为: 取 JavaBean 对象: 取 JavaBean 对象也很容易,因为 JavaBean 自身有一些其他属性,所以咱们就可以使用 {对象名.对象属性} 或者 {对象名['对象属性']} 来取值,这和 JavaScript 语法是不是很相似呢!除此之外,如果该 JavaBean 如果写了 get 方法,咱们也可以通过 get 方法取值例如
<h2>JavaBean对象</h2>
<table bgcolor="#ffe4c4" border="1">
<tr>
<td>介绍</td>
<td th:text="${user.name}"></td>
</tr>
<tr>
<td>年龄</td>
<td th:text="${user['age']}"></td>
</tr>
<tr>
<td>介绍</td>
<td th:text="${user.getDetail()}"></td>
</tr>
</table>
运行结果为:
取 List 集合 (each):
因为 List 集合是个有序列表,里面内容可能不止一个,你需要遍历 List 对其中对象取值,而遍历需要用到标签: th:each
, 具体使用为 <tr th:each="item:${userlist}">
, 其中 item 就相当于遍历每一次的对象名,在下面的作用域可以直接使用,而 userlist 就是你在 Model 中储存的 List 的名称。完整的代码为:
<h2>List取值</h2>
<table bgcolor="#ffe4c4" border="1">
<tr th:each="item:${userlist}">
<td th:text="${item}"></td>
</tr>
</table>
运行结果为: 直接取 Map: 很多时候我们不存 JavaBean 而是将一些值放入 Map 中,再将 Map 存在 Model 中,我们就需要对 Map 取值,对于 Map 取值你可以 {Map名['key']} 来进行取值。也可以通过 {Map名.key} 取值,当然你也可以使用
<h2>Map取值</h2>
<table bgcolor="#8fbc8f" border="1">
<tr>
<td>place:</td>
<td th:text="${map.get('place')}"></td>
</tr>
<tr>
<td>feeling:</td>
<td th:text="${map['feeling']}"></td>
</tr>
</table>
运行结果为:
遍历 Map:
如果说你想遍历 Map 获取它的 key 和 value 那也是可以的,这里就要使用和 List 相似的遍历方法,使用 th:each="item:${Map名}"
进行遍历,在下面只需使用 item.key
和 item.value
即可获得值。完整代码如下:
<h2>Map遍历</h2>
<table bgcolor="#ffe4c4" border="1">
<tr th:each="item:${map}">
<td th:text="${item.key}"></td>
<td th:text="${item.value}"></td>
</tr>
</table>
变量表达式不仅可以写成 ${…},而且还可以写成 *{…}。
但是,有一个重要的区别:星号语法对选定对象而不是整个上下文评估表达式。也就是说,只要没有选定的对象,美元 ( ${…}
) 和星号 ( *{...}
) 的语法就完全一样。
什么是选定对象?使用 th:object
属性的表达式的结果。就可以选定对象,具体实例如下:
<div th:object="${user}">
<p>Name: <span th:text="*{name}">赛</span>.</p>
<p>Age: <span th:text="*{age}">18</span>.</p>
<p>Detail: <span th:text="*{detail}">好好学习</span>.</p>
</div>
当然 *{…}
也可和 ${…}
混用。上面的代码如果不使用选定对象,完全等价于:
<div >
<p>Name: <span th:text="*{user.name}">赛</span>.</p>
<p>Age: <span th:text="${user.age}">18</span>.</p>
<p>Detail: <span th:text="${user.detail}">好好学习</span>.</p>
</div>
运行结果为:
文本外部化是从模板文件中提取模板代码的片段,以便可以将它们保存在单独的文件 (通常是.properties 文件) 中,文本的外部化片段通常称为 “消息”。通俗易懂的来说 #{…}
语法就是用来读取配置文件中数据的。在 Thymeleaf 你可以使用 #{...}
语法获取消息,具体实例代码如下:
首先在 templates 目录下建立 home.properties
中写入以下内容:
bigsai.nane=bigsai
bigsai.age=22
province=Jiang Su
在 application.properties
中加入以下内容:
spring.messages.basename=templates/home
这样我们就可以在 Thymeleaf 中读取配置的文件了,完整代码如下:
<h2>消息表达</h2>
<table bgcolor="#ffe4c4" border="1">
<tr>
<td>name</td>
<td th:text="#{bigsai.name}"></td>
</tr>
<tr>
<td>年龄</td>
<td th:text="#{bigsai.age}"></td>
</tr>
<tr>
<td>province</td>
<td th:text="#{province}"></td>
</tr>
</table>
运行结果为:
到这里本次 Thymeleaf 的入门学习就结束了,通过本次学习你可能更深入了解了 Thymeleaf 以及模板引擎,也对 Thymeleaf 的动静分离、开箱即用的一些特性估计有了更深入的了解。你也具备 Thymeleaf 的基本使用能力,能够用 Thymeleaf 进行网页的快速开发……
但 Thymeleaf 的内容绝非只有这么一点点,本篇旨在带你从一个对 Thymeleaf 概念为零的状态到一个能够较为清晰明了的认识和使用 Thymeleaf,对于 Thymeleaf 的内容远远不止上面所涉及到的,对于一些算术运算、条件表达式等等其他内容还需要你自己到 Thymeleaf 官网去学习研究。
Thymeleaf 是一种 Java 模板引擎,被 Springboot 官方推荐,大大提高开发效率,提高代码复用率。虽然在当今 Ajax 更为流行,但对于后端开发工程师掌握 Thymeleaf,拥有快速开发网页能力,还是很有必要的!本篇就到这里了,我们下次再见!
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有