模板引擎Thymeleaf 介绍及使用
Posted 吞吞吐吐大魔王
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模板引擎Thymeleaf 介绍及使用相关的知识,希望对你有一定的参考价值。
文章目录
1. 服务器生成动态页面的方式
这里介绍两种常用的服务器生成动态页面的方式:服务器渲染和客户端渲染
渲染就是把数据和页面结合起来
1.1 客户端渲染(前后端分离)
客户端渲染流程:
客户端渲染是在请求回数据后就开始渲染了,只是有些数据还没有拿到,故暂时没法渲染。但是大部分页面的内容是可以获取到的,因此客户端渲染可以完成页面的部分刷新。
客户端渲染示例: 淘宝某商品的评论,我们点击该商品评论区的其它页面,只是刷新了评论区域,整个商品页面并没有刷新,浏览器的网址也没有变。当我们点击评论区的下一页时,客户端就会向服务器发送 Ajax 请求,之后就会拿到该页评论信息,并对这个局部区域进行渲染
客户端渲染的特点:
- 客户端通过 Ajax 的方式和服务器进行交互
- 服务器返回的不是完整的 html,通常只是纯粹的数据,这些数据常见的以 json 的方式来组织
客户端渲染的优点:
- 能够让前后端进行充分的解耦,前后端的开发互不干扰,也能各自进行测试
- 可以向用户快速展示页面的内容,增加用户体验
- 通过爬虫爬取响应的内容会增加一定的难度
客户端渲染的缺点:
- 前后端交互的次数比较多
- 一个页面可能需要多组 Ajax 来获取完整的数据,效率稍微低一些
- 不利于 SEO 搜索引擎优化,即搜索引擎搜索不到客户端渲染的数据
1.2 服务器渲染(使用模板引擎)
服务器渲染流程:
服务器渲染是在请求后,服务器对于请求的网页文件直接渲染好,然后返回给客户端。
服务器渲染示例: 淘宝上搜索某商品,当我们通过销量、价格、信用等分类查询该商品时,整个页面都会被刷新,浏览器的网址也会改变
服务器渲染的特点:
- 服务器返回一整个 html 页面
- html 页面上的一些动态数据,往往是通过“模板引擎”的方式来进行动态替换的
服务器渲染的优点:
- 前后端交互次数比较少,一次 HTTP 请求/响应,就能够拿到一个完整的页面,比较高效
- 利于 SEO 搜索引擎优化,即能被搜索引擎搜索到,能向用户展示你网页的内容
服务器渲染的缺点:
- 前后端代码不能充分解耦合,前后端开发很难进行明确分工,不能够独立测试
- 如果数据量过大,服务器渲染的时间就会过长,造成浏览器的暂时性空白
- 页面上的数据容易被爬虫获取
2. 模板引擎
2.1 模板引擎介绍
-
模板引擎(template engine): 是为了使用户界面与业务数据分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的 HTML 文档。当服务器将模板中动态变化的部分计算好之后,将模板中的占位符给替换成计算的结果,然后将这个组装好的 HTML 格式的字符串返回给浏览器。
-
模板(template): 就是一个 HTML,只不过这个 HTML 是把一些动态变化的数据给挖空,用特殊符号代替。
2.2 模板引擎的作用
- 模板引擎可以让(网站)程序实现界面与数据分离,业务代码与逻辑代码的分离,这就大大提升了开发效率,并且良好的设计也使得代码重用变得更加容易。
- 模板引擎不只是可以让你实现代码分离(业务逻辑代码和用户界面代码),也可以实现数据分离(动态数据与静态数据),还可以实现代码单元共享(代码重用),甚至是多语言、动态页面与静态页面自动均衡(SDE)等等与用户界面可能没有关系的功能。
2.3 常见的模板引擎
-
Thymeleaf
Thymeleaf 是新一代 Java 模板引擎,与 Velocity、FreeMarker 等传统 Java 模板引擎不同,Thymeleaf 支持 HTML 原型,其文件后缀为
.html
,因此它可以直接被浏览器打开,此时浏览器会忽略未定义的 Thymeleaf 标签属性,展示 Thymeleaf 模板的静态页面效果;当通过 Web 应用程序访问时 Thymeleaf 会动态地替换掉静态内容,使页面动态显示。 -
FreeMaker
在所有采用网页静态化手段的网站中,FreeMarker 使用的比例大大的超过了其他的一些技术。HTML 静态化也是某些缓存策略使用的手段,对于系统中频繁使用数据库查询但是内容更新很小的应用,可以使用 FreeMarker 将 HTML 静态化。比如一些网站的公用设置信息,这些信息基本都是可以通过后台来管理并存储在数据库中,这些信息其实会大量的被前台程序调用,每一次调用都会去查询一次数据库,但是这些信息的更新频率又会很小,因此也可以考虑将这部分内容进行后台更新的时候进行静态化,这样就避免了大量的数据库访问请求,提高了网站的性能。
-
Enjoy
Enjoy 是基于 Java 语言的极轻量极模板引擎且不依赖任何第三方。极简设计仅由 if、for、switch、set、define、include、render 七个核心指令,让学习成本低到极致。独创 DKFF(Dynamic Key Feature Forward)词法分析算法与 DLRD(Double Layer Recursive Descent)语法分析算法,避免使用 javacc、antlr、jflex 生成器,令代码量少到极致。
-
Velocity
Velocity 是一个基于 Java 的模板引擎。它允许任何人使用简单但功能强大的模板语言来引用 Java 代码中定义的对象。
-
JSP
JSP 虽然是一款功能比较强大的模板引擎,并被广大开发者熟悉,但它前后端耦合比较高。比如说前端的 HTML 页面还要手动修改成 JSP 页面,大大加重了工作量,而且动态和静态资源也是耦合性太高。其次是 JSP 页面的效率没有 HTML 高,因为 JSP 是同步加载。而且 JSP 需要tomcat,但又不支持 nginx 等,已经跟不上时代的潮流。
3. Thymeleaf
3.1 Thymeleaf 介绍
Thymeleaf 基本介绍:
Thymeleaf 是新一代 Java 模板引擎,与 Velocity、FreeMarker 等传统 Java 模板引擎不同,Thymeleaf 支持 HTML 原型,其文件后缀为 .html
,因此它可以直接被浏览器打开,此时浏览器会忽略未定义的 Thymeleaf 标签属性,展示 Thymeleaf 模板的静态页面效果;当通过 Web 应用程序访问时 Thymeleaf 会动态地替换掉静态内容,使页面动态显示。
Thymeleaf 的特点:
- 动静结合:Thymeleaf 既可以直接使用浏览器打开,查看页面的静态效果,也可以通过 Web 应用程序进行访问,查看动态页面效果。
- 开箱即用:Thymeleaf 提供了 Spring 标准方言以及一个与 SpringMVC 完美集成的可选模块,可以快速的实现表单绑定、属性编辑器、国际化等功能。
- 多方言支持:它提供了 Thymeleaf 标准和 Spring 标准两种方言,可以直接套用模板实现 JSTL、 OGNL 表达式;必要时,开发人员也可以扩展和创建自定义的方言。
- 与 SpringBoot 完美整合:SpringBoot 为 Thymeleaf 提供了的默认配置,并且还为 Thymeleaf 设置了视图解析器,因此 Thymeleaf 可以与 Spring Boot 完美整合。
3.2 Thymeleaf 语法规则
Thymeleaf 作为一种模板引擎,它拥有自己的语法规则。Thymeleaf 的语法分为两类:标准表达式语法和 th 属性
3.2.1 标准表达式语法
Thymeleaf 模板引擎支持多种表达式,以下重点介绍变量表达式
变量表达式:$表达式
获取对象的属性和方法
// 获取 result 对象的 from 属性 $result.from
使用内置的基本对象(Thymeleaf 中常用的内置基本对象如下)
内置基本对象 描述 #ctx
上下文对象 #vars
上下文变量 #locale
上下文的语言环境 #request
HttpServletRequest
对象#response
HttpServletResponse
对象#session
HttpSession
对象#servletContext
ServletContext
对象使用内置的工具对象
内置的工具对象 描述 #strings
字符串工具对象,常用的方法有:equals、equalsIgnoreCase、length、trim、toUpperCase、toLowerCase、indexOf、substring、replace、startsWith、endsWith,contains 和 containsIgnoreCase 等 #numbers
数字工具对象,常用的方法有:formatDecimal 等 #bools
布尔工具对象,常用的方法有:isTrue 和 isFalse 等 #arrays
数组工具对象,常用的方法有:toArray、length、isEmpty、contains 和 containsAll 等 #lists 或 #sets
List/Set 集合工具对象,常用的方法有:toList、size、isEmpty、contains、containsAll 和 sort 等 #maps
Map 集合工具对象,常用的方法有:size、isEmpty、containsKey 和 containsValue 等 #dates
日期工具对象,常用的方法有:format、year、month、hour 和 createNow 等
选择表达式:*表达式
选择变量表达式与变量表达式功能基本一致,只是在变量表达式的基础上增加了与
th:object
的配合使用。当使用th:object
存储一个对象后,我们可以在其后代中使用选择变量表达式获取该对象中的属性,其中*
即代表该对象。
链接表达式:@表达式
不管是静态资源的引用,还是 form 表单的请求,凡是链接都可以用链接表达式
消息表达式:#表达式
消息表达式一般用于国际化的场景
片段表达式:~表达式
片段引用表达式用于在模板页面中引用其他的模板片段
3.2.2 th 属性
Thymeleaf 提供了大量的 th 属性,这些属性可以直接在 HTML 标签中使用,其中常用 th 属性及其示例如下表。
属性 | 功能 | 示例 |
---|---|---|
th:text | 文本替换(能够转移特殊字符) | |
th:[HTML 标签属性] | 设置任意的 HTML 标签的属性的值 | |
th:if | 根据条件判断是否需要展示此标签 | |
th:switch | 与 th:case 配合使用,根据不同的条件展示不同的内容 | |
th:each | 循环访问元素,支持 Iterable、Map、数组等 | |
th:action | 替换表单的提交地址 | |
th:src | 替换 HTML 中的 src 属性 | |
th:id | 替换 HTML 中的 id 属性 | |
th:value | 替换 HTML 中的 value 属性 | |
th:style | 设置标签样式 |
3.3 Thymeleaf 使用流程
接下来通过写一个猜数字的程序来演示 Thymeleaf 模板引擎的使用流程
-
创建一个 Maven 项目,引入 Thymeleaf 依赖(在 maven 中央仓库搜索 Thymeleaf,选择合适版本)
<!-- https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf --> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf</artifactId> <version>3.0.15.RELEASE</version> </dependency>
-
编写 HTML 模板文件(在
webapp/WEB-INF
目录下再创建一个template
目录用于存放 HTML 模板文件)<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>猜数字游戏</title> </head> <body> <div> <from action="guessNum" method="post"> <span>请输入要猜的数字:</span> <input type="text" name="toGuess"> <input type="submit" value="猜"> </from> </div> <div> 结果:<span th:text="$result"></span> </div> </body> </html>
<span th:text="$result"></span>
将 result 对象替换成该 span 标签的文本内容- result 这个值是从后台渲染而来,如果没网络(直接打开 html 文件)的时候静态数据为空,因为此时 span 标签中没有内容,你要是写了,那就由对应的内容。而如果通过网络访问那么内容将是程序员在 Servlet 中通过计算生成的一个变量
-
编写 Servlet 代码
- 初始化模板引擎对象
- 创建解析器,并设置模板的参数,并将这个模板引擎对象关联这个解析器
- 创建模板的上下文对象,用于对模板中要动态修改的数据进行设置
- 执行模板引擎
import org.thymeleaf.TemplateEngine; import org.thymeleaf.context.WebContext; import org.thymeleaf.templateresolver.ServletContextTemplateResolver; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.WebConnection; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Random; // 猜数字 @WebServlet("/guessNum") public class GuessNumServlet extends HttpServlet private Random random = new Random(); // 初始化生成的随机数 private int num = 0; // private TemplateEngine engine = new TemplateEngine(); // 在 init 方法中初始化模板引擎 @Override public void init() throws ServletException 创建一个 ServletContextTemplateResolver 对象,resolver 表示解析器,这个对象是的功能就是从磁盘上加载 html 模板文件 ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(getServletContext()); // 设置模板所在的目录 resolver.setPrefix("/WEB-INF/template/"); // 设置模板的文件类型 resolver.setSuffix(".html"); // 设置模板的编码方式 resolver.setCharacterEncoding("utf-8"); // 给模板引擎对象设置解析器,将模板引擎对象和模板关联起来 engine.setTemplateResolver(resolver); // 通过 doGet 从服务器获取到猜数字的初始界面和生成的随机数字 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException // 设置请求的编码方式, req.setCharacterEncoding("utf8"); resp.setContentType("text/html;charset=utf8"); num = random.nextInt(100)+1; WebContext webContext = new WebContext(req, resp, getServletContext()); engine.process("guessNum",webContext, resp.getWriter()); // 通过 doPost 从服务器获取到猜完数字后的结果界面 @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException resp.setContentType("text/html;charset=utf8"); int toGuess = Integer.parseInt(req.getParameter("toGuess")); String result = ""; if(toGuess > num) result += "猜大了!"; else if(toGuess < num) result += "猜小了!"; else result += "猜对了!"; WebContext webContext = new WebContext(req, resp, getServletContext()); webContext.setVariable("result", result); engine.process("guessNum",webContext, resp.getWriter());
TemplateEngine
对象表示模板引擎,用于进行页面的渲染ServletContextTemplateResolver
对象表示“解析器”,用于加载 HTML 模板getServletContext()
方法可以获取到这个 webapp 的上下文对象ServletContext
(每个 webapp 都有一个ServletContext
,并且一个 webapp 中可以有多个 Servlet,这多个 Servlet 中是可以共享ServletContext
对象的,可以基于这个上下文对象来传递数据)WebContext
对象表示模板上下文,本质是一个哈希表,里面有三个固定参数req
、resp
、getServletContext()
。通过这个对象的setVariable()
方法就可以动态替换模板中的可修改数据,该方法的第一个参数是模板中的要动态替换的变量,第二个参数是程序员自己计算生成的变量TemplateEngine
类的engine()
方法就可以启动模板引擎。该方法的第一个参数是模板文件名,第二个参数是模板上下文对象,第三个参数是resp.getWriter()
-
代码效果展示
以上是关于模板引擎Thymeleaf 介绍及使用的主要内容,如果未能解决你的问题,请参考以下文章
SpringBoot基础篇- 静态资源的访问及Thymeleaf模板引擎的使用