> 文章列表 > 如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

编译软件:IntelliJ IDEA 2019.2.4 x64
操作系统:win10 x64 位 家庭版
服务器软件:apache-tomcat-8.5.27


目录

  • 一. 什么是Thymeleaf?
  • 二. MVC
    • 2.1 为什么需要MVC?
    • 2.2 MVC是什么?
    • 2.3 MVC和三层架构之间的关系及工作流程
  • 三. Thymeleaf的工作原理
  • 四. Thymeleaf的优势
  • 四. Thymeleaf的准备知识
    • 4.1 物理视图
    • 4.2 逻辑视图
  • 五. 如何编写第一个Thymeleaf的程序?
  • 六.Thymeleaf的基本语法
    • 6.1 th名称空间
    • 6.2 修改标签的文本值(双标签)
    • 6.3 修改标签的属性值(单标签和双标签)
    • 6.4 解析URL地址
    • 6.5 获得域对象中的数据
      • 6.5.1 获取应用域对象中的数据
      • 6.5.2 获取会话域对象中的数据(Httpsession session)
      • 6.5.3 获取请求域对象中的数据(HttpservletRequest request)
    • 6.6 获得请求参数
      • 6.6.1 根据一个参数名获取一个参数值
      • 6.6.2 根据一个参数名获取多个参数值
    • 6.7 内置对象
      • 6.7.1 基本内置对象
      • 6.7.2 公共内置对象
    • 6.8 OGNL( 对象-图导航语言)
      • 6.8.1 简单对象
      • 6.8.2 稍微复杂的对象
      • 6.8.3 list集合(简单集合)
      • 6.8.4 复杂集合(list集合存储对象)
      • 6.8.5 复杂集合(map集合存储对象)
    • 6.9 分支与迭代
      • 6.9.1 分支,控制元素的是否显示
        • 6.9.1.1 th:if 和 th:unless
        • 6.9.1.2 th:switch和th:case
      • 6.9.2 迭代(遍历循环)
        • 6.9.2.1 简单数组迭代
        • 6.9.2.2 复杂数组迭代
    • 6.10 Thymeleaf包含其他模板文件
      • 6.10.1 应用场景
      • 6.10.2 操作步骤
        • ①给公共的代码片段起个名字
        • ②在其他页面根据名字引用
          • a. th:replace
          • b. th:insert
          • c. th:include
      • 6.10.3 综合案例

一. 什么是Thymeleaf?

Thymeleaf是一种用于Java web应用程序的服务器端模板引擎可以将HTML、XML、JavaScript等静态文件与动态数据(如表单数据、数据库中的数据等)结合起来,在服务器端生成动态的Web页面。

简而言之,它的主要作用就是在静态页面上渲染显示动态数据

Thymeleaf的设计目标是使Web开发变得更加自然和可维护。相比于其他模板引擎,Thymeleaf提供了更好的语法支持和功能,例如标记优雅降级、敏捷布局、动态URL、等,因此它被广泛地应用于Spring框架的开发中。


二. MVC

2.1 为什么需要MVC?

  • 提高代码的可维护性:MVC模式将应用程序分成三个互不干扰的部分,使代码更加清晰简洁,易于阅读和
  • 支持程序的可扩展性和可重用性:MVC模式使得开发人员在修改应用程序时更加轻松自如,只需要修改特定的代码库即可,而不会影响到其他部门的代码。这种思路与基于组件或者服务的方法相似。
  • 提升用户体验:MVC模式开发出来的应用程序中,UI
    界面(视图)负责直接呈现数据给用户。同时,视图也不包含任何关于业务领域或者实体(模型)的信息。控制器分离了模型和视图,对用户请求进行处理并起到转发作用,使得界面更加优秀、交互式、快速响应让用户体验更好。

2.2 MVC是什么?

MVC,英文全称为Model-View-Controller(模型-视图-控制器),它是一种常用于软件工程中的设计模式

Model模型 : javaBean(User/Book等类)

View视图 : html+服务器的动态数据

什么叫服务器的动态数据?如下图所示

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

Controller控制器 : 在web阶段可以暂时将Servlet视为控制器

2.3 MVC和三层架构之间的关系及工作流程

MVC的架构关系及相应的工作流程图解如下所示:

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

工作流程:

当浏览器向服务器发起请求时,请求被Servlet(控制器)所接收,Servlet会根据请求的内容调用Service(业务逻辑层)去处理相应的业务需求,Service会根据业务需要,会调用DAO层去处理数据,DAO层连接数据库获取相应的数据,然后回传数据给Service,Service根据数据处理好业务需求,将结果回传给Servlet,Servlet将结果传给Thymeleaf,让它渲染页面,从而生成的view对象响应给浏览器。


三. Thymeleaf的工作原理

原理:

从上节中的MVC架构工作流程图中可知,当Servlet接收到service(业务层)给的结果的时候,首先是到视图层(Thymeleaf),将动态数据和HTML进行拼接,从而产生一个View对象(视图),将view对象展示在浏览器上(用户看到的就是有动态数据的网页)


四. Thymeleaf的优势

  • SpringBoot官方推荐使用的视图模板技术,和SpringBoot完美整合
  • 不经过服务器运算仍然可以直接查看原始值,对前端工程师更友好

四. Thymeleaf的准备知识

4.1 物理视图

释义:

在Servlet中,将请求转发到一个HTML页面文件时,使用的完整的转发路径就是物理视图。

如下图所示:

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

上述图中所有的HTML页面都放在统一的目录(/WEB-INF/pages下),转发地址已经呈现出一种明显的规律。

将上面所有的物理视图抽取出来

/WEB-INF/pages/a.html
/WEB-INF/pages/abc.html
/WEB-INF/pages/admin.html

/WEB-INF/pages/index.html
/WEB-INF/pages/root.html

路径的开头都是/WEB-INF/pages/

路径的结尾都是:.html

对此,路径的开头部分我们称之为视图前缀,路径的结尾部分我们称之为视图后缀

4.2 逻辑视图

物理视图:视图前缀+逻辑视图+视图后缀

逻辑视图控制页面跳转的位置

例如:物理视图/WEB-INF/pages/a.html/WEB-INF/pages/ 是视图前缀,.html是视图后缀,中间的部分a是逻辑视图,即在servlet中页面跳转的代码语句中要写的跳转位置


五. 如何编写第一个Thymeleaf的程序?

程序需求:

在index.html中访问HelloServlet,由HelloServlet传给Thymeleaf,使其将请求域中的数据(这是给服务器的数据)渲染至admin.html,响应给浏览器

步骤:

①导入Thymeleaf的jar包(共8个)

ps:和导入Beanutils的jar包步骤一致,请自行参阅我的这篇博客Servlet 之超详解【2023年最新版】 第九节的内容。

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

②在web.xml中配置全局初始化参数

<!--thymeleaf的前缀和后缀-->
<context-param>
<param-name>view-prefix</param-name>
<param-value>/pages/</param-value>
</context-param>
<context-param>
<param-name>view-suffix</param-name>
<param-value>.html</param-value>
</context-param>

③创建Thymeleaf的模板类ViewBaseServlet(直接复制下面的代码,粘贴到自己的项目下ViewBaseServlet中即可),该类是 HttpServlet 的子类,专门处理 Web 应用程序中视图页面的呈现。在后期使用框架时,该类会被取代。

代码演示如下:

import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.WebContext;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;public class ViewBaseServlet extends HttpServlet {private TemplateEngine templateEngine;@Overridepublic void init() throws ServletException {//对servlet初始化的(对象创建后立刻初始化)// 1.获取ServletContext对象ServletContext servletContext = this.getServletContext();// 2.创建Thymeleaf解析器对象ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(servletContext);// 3.给解析器对象设置参数// ①HTML是默认模式,明确设置是为了代码更容易理解templateResolver.setTemplateMode(TemplateMode.HTML);// ②设置前缀String viewPrefix = servletContext.getInitParameter("view-prefix");templateResolver.setPrefix(viewPrefix);// ③设置后缀String viewSuffix = servletContext.getInitParameter("view-suffix");templateResolver.setSuffix(viewSuffix);// ④设置缓存过期时间(毫秒)templateResolver.setCacheTTLMs(60000L);// ⑤设置是否缓存templateResolver.setCacheable(true);// ⑥设置服务器端编码方式templateResolver.setCharacterEncoding("utf-8");// 4.创建模板引擎对象templateEngine = new TemplateEngine();// 5.给模板引擎对象设置模板解析器templateEngine.setTemplateResolver(templateResolver);}//就是Thymeleaf要进行渲染的方法,后期如果要进行页面的渲染的话,需要调用此方法protected void processTemplate(String templateName, HttpServletRequest req, HttpServletResponse resp) throws IOException {// 1.设置响应体内容类型和字符集resp.setContentType("text/html;charset=UTF-8");// 2.创建WebContext对象WebContext webContext = new WebContext(req, resp, getServletContext());// 3.处理模板数据templateEngine.process(templateName, webContext, resp.getWriter());}
}

注意:ViewBaseServlet类里的

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

上述红框中的两个名称要和web.xml中全局初始化参数里设置的前缀名和后缀名保持一致,如下图所示

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

代码演示如下:

④创建HelloServlet(计划用HelloServlet传给thymeleaf去渲染网页,响应给客户端),并在web.xml中设置它的访问路径(/hello)

<!--  设置访问HelloServlet的路径 /hello  --><servlet><servlet-name>HelloServlet</servlet-name><servlet-class>Servlet.HelloServlet</servlet-class></servlet><servlet-mapping><servlet-name>HelloServlet</servlet-name><url-pattern>/hello</url-pattern></servlet-mapping>

⑤创建index.html,在其中设置访问HelloServlet的超链接(计划访问后台的HelloServlet)

代码演示如下:

<a href="hello">点击访问HelloServlet</a>

⑥HelloServlet(要通过Thymeleafi进行页面的渲染,需要继承ViewBaseServlet)

代码演示如下:

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;public class HelloServlet extends ViewBaseServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request,response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("访问到了HelloServlet类中的doGet方法");//这里假设业务已经处理好了,HelloServlet已经拿到了业务层传过来的结果System.out.println("HelloServlet已经拿到了业务层的处理结果....");//给响应(跳转至admin.html,并且msg的数据展示在网页上)String msg="这是给服务器的数据";//HelloServlet发送给Themeleaf,让它对页面进行渲染//设置请求域中的共享数据request.setAttribute("msg",msg);this.processTemplate("admin",request,response);//Themeleaf的原理也是转发}
}

⑦admin.html中需要写thymealf的渲染表达式

代码演示如下:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<h1>admin页面</h1>
<h2 th:text="${msg}">这是服务器传过来的msg</h2>
</body>
</html>

注意:

要想使用thymealf的渲染表达式,就必须满足下面的两点要求

a.需要在html标签内设置th这个名称空间

示例代码如下:

<html lang="en"xmlns:th="http://www.thymeleaf.org">

b.在一个标签内通过添加属性的方式,让thymeleaf对该标签的标签体内容进行渲染(覆盖)

示例代码如下:

<h2 th:text="${msg}">放服务器传过来的msg数据</h2>

其中 $(msg},是从请求域内获得key值为msg的value值


六.Thymeleaf的基本语法

6.1 th名称空间

Thymeleaf所有的表达式都是通过属性的方式添加,th:表达式内容

添加的位置html标签的属性上

xmlns:th="http://www.thymeleaf.org"

6.2 修改标签的文本值(双标签)

语法:

th:text=“新值”

示例代码如下:

<h2 th:text="${msg}">放服务器传过来的msg数据</h2>

从请求域中获取key为msg的value值写入标签体中,原有的标签体内容会被覆盖

6.3 修改标签的属性值(单标签和双标签)

语法:

th:属性名=“新值”

示例代码如下::

<input type="text"value="这是原始值"th:value="${msg}">

6.4 解析URL地址

目的:

拿到urI中的上下文路径

语法:

@{/)

用途:

a.用在base标签上

示例代码如下:

<base href="" th:href="@{/}">

b.作为请求的路径

示例代码如下:

//写法一:
<a href="root?id=101&name=jack">Rootservlet01</a>
//写法二:
<a th:href="@{/root(id=101,name='jack',age=20)}">RootServlet02</a>

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

注意

这里存在一个问题,在以下两个html网页中,均设了使用thymeleaf去动态的获取上下文路径,使其可以被服务器将上下文路径渲染进base标签里。index网页中故意写错base标签中的href属性值(/day07_Thymeleaf_war_exploded123/),希望原来的错误href属性值可以被渲染为正确的路径(/day07_Thymeleaf_war_exploded/)

代码如下所示:

//index.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><base href="/day07_Thymeleaf_war_exploded123/" th:href="@{/}"><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<a href="hello">访问HelloServlet</a>
</body>
</html>
//admin.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><!--  使用Themeleaf动态获取上下文路径  --><base href="" th:href="@{/}"><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<h1>admin页面</h1>
<h2 th:text="${msg}">这是服务器传过来的msg</h2>
输入: <input type="text" value="这是原始值" th:value="${msg}"><br>
<a href=-""th:href="${msg}">a标签</a><br/>
上下文路径:<h2 th:text="@{/}"></h2><!-- 传递参数 -->
<a href="root?id=101&name=jack">Rootservlet01</a>
<a th:href="@{/root(id=101,name='jack',age=20)}">RootServlet02</a>
</body>
</html>

代码运行后测试结果显示渲染失败

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

原因分析:

index.html中的base标签写入的是错误的项目路径,即无法从正确的项目路径去访问HelloServlet,自然也就不会别Thymeleaf所渲染

结论:

如果你的网页想使用thymeleaf的渲染表达式的话,就必须经过Servlet然后在经过Thymeleaf进行渲染才可以,在实际开发中项目内所有的网页都需要thymeleaf渲染(都需要过Servlet在过Thymeleaf模板引擎)

解决方案:

让index.html去过一遍servlet,将index.html移动至本地动态web项目下web/pages里,这样它可以Thymeleaf所识别,新增一个ToindexServlet,并同时在web-xml中设置访问ToindexServlet的路径

代码演示如下:


import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;public class ToindexServlet extends ViewBaseServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.processTemplate("index",request,response);}
}

在浏览器地址栏里键入 “http://localhost:8080/day07_Thymeleaf_war_exploded/index”,以get形式访问ToindexServlet,调用其doGet方法对index.html进行渲染

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

附注:

在上述代码不变的前提下,你在web.xml中修改访问ToindexServlet的路径为"/index.abc" or “/index.html” 。这种写法在web.xml中没有语法问题,但是你在浏览器网址栏输入

http://localhost:8080/day07_Thymeleaf_war_exploded/index.html

时才可以访问到index.html,看似是在项目路径下直接找的index.html,实则不然,这是项目路径下键入访问ToindexServlet的路径,由它再过Thymeleaf渲染Index.html,然后再呈现在浏览器中供客户观看

6.5 获得域对象中的数据

6.5.1 获取应用域对象中的数据

语法:

ServletContext application(一般取别名为application)
${appliaction.应用域中的key值)

示例代码如下:

//在HelloServlet中设置应用域的数据
ServletContext application = request.getServletContext();
application.setAttribute("applicationMsg","这是应用域中的applicationMsg数据");
//在admin.html中设置
<!-- 从应用域中获取applicationMsg给admin渲染 -->
<p th:text="${application.applicationMsg}"></p>

注意:

${appliaction.应用域中的key值)中的application和ServletContext对象的别名没有丝毫关系,它是写死的,无论ServletContext对象的别名叫什么。

6.5.2 获取会话域对象中的数据(Httpsession session)

语法:

${session.会话域中的key值}

6.5.3 获取请求域对象中的数据(HttpservletRequest request)

语法:

${请求域中的key}

ps:详细应用在上述的章节内容已有展示,故不作涉及

6.6 获得请求参数

语法:

${param.请求参数的key值)

6.6.1 根据一个参数名获取一个参数值

案例:根据在index.html里访问adminServlet的超链接添加i请求参数,由adminServlet传给thymeleaf渲染admin.html并响应给客户端,admin.html可以获取请求参数并显示

示例代码如下:

//在index.html中访问adminServlet的超链接中添加请求参数
<a href="admin?id=101&name=jack">访问adminServlet</a>
//在adminServlet中获取请求参数并让thymeleaf渲染admin.html,响应给浏览器
String id = request.getParameter("id");
System.out.println("id="+id);
String name = request.getParameter("name");
System.out.println("name="+name);
//调用Thymeleaf渲染admin.html并响应给客户端
this.processTemplate("admin",request,response);
<!-- admin.html获取请求参数 -->
获取请求参数:
<p th:text="${param.id}"></p>
<p th:text="${param.name}"></p>

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

6.6.2 根据一个参数名获取多个参数值

案例:根据在index.html里访问adminServlet的超链接添加i请求参数(同一个参数有多个残数值),由adminServlet传给thymeleaf渲染admin.html并响应给客户端,admin.html获取请求参数并显示

示例代码如下:

//在index.html中访问adminServlet的超链接中添加请求参数(同一个参数名有多个参数值)
<a href="admin?hobbys=basketball&hobbys=run&hobbys=rap">访问adminServlet</a>
//在adminServlet中获取一个参数名获取多个参数值,让thymeleaf渲染admin.html,响应给浏览器看
String[] hobbys = request.getParameterValues("hobbys");
System.out.println(Arrays.toString(hobbys));
<!-- 在admin.html中获取一个参数名获取多个参数值 --->
<p th:text="${param.hobbys}"></p>
<!-- 获取参数hobbys第一个参数值 -->
<p th:text="${param.hobbys[0]}"></p>
<!-- 获取参数hobbys第二个参数值 -->
<p th:text="${param.hobbys[1]}"></p>
<!-- 获取参数hobbys第三个参数值 -->
<p th:text="${param.hobbys[2]}"></p>

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

6.7 内置对象

释义:

可以直接使用的对象

6.7.1 基本内置对象

常用基本内置对象:

#request就是Servlet中的HttpServletRequest对象
#response 就是Servlet中的HttpServletResponse对象
#session就是Servlet中的Httpsession对象
#servletContext就是Servlet中的ServletContext对象

案例:获取基本内置对象request的主机名

代码示例如下:

<!-- 获取基本内置对象request的主机名 -->
<p th:text="${#request.getServerName()}"></p>
<!-- 获取request的上下文路径 -->
<p th:text="${#request.getContextPath()}"></p>
.....

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

6.7.2 公共内置对象

#strings提供了很多对字符串操作的方法
#arrays提供了操作数组的常用方法
#lists提供了操作List集合的捞用方法
#sets提供了操作set集合的常用方法
#maps提供了操作Map集合的常用方法

案例:演示#strings,#arrays,#lists等部分常用公共内置对象的部分常用方法

//在请求域中添加一个数据(数组)
String[] names={"java","python","lua"};
request.setAttribute("names",names);//在请求域中添加一个数据(list集合)
List<String> list=new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
request.setAttribute("list",list);
//调用Thymeleaf渲染root.html并响应给客户端
this.processTemplate("root",request,response);
<!--Arrays中的方法:-->
<p>Arrays中的方法:</p>
<p th:text="${#arrays.length(names)}"></p>
<p th:text="${#arrays.contains(names,'java')}"></p><!--List中的方法:-->
<p>list中的方法:</p>
<p th:text="${#lists.size(list)}"></p>
<p th:text="${#lists.isEmpty(list)}"></p>

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

6.8 OGNL( 对象-图导航语言)

对象-图的概念:

从根对象触发,通过特定的语法,逐层访问对象的各种属性。

简而言之:

就是将复杂的对象或者集合放在域对象内,Thymeleaf去获取这些数据在网页渲染

6.8.1 简单对象

案例:请求域内共享简单对象employee,rootServlet调用Thymeleaf渲染root.html并响应给客户端,root.html要显示动态数据(请求域内的简单对象employee)

代码示例如下:

//在rootServle中创建一个employee对象
Employee employee=new Employee(101,"张三",0,7800.0);
//请求域内共享一个简单对象
request.setAttribute("emp",employee);
//调用Thymeleaf渲染root.html并响应给客户端
this.processTemplate("root",request,response);

<p>简单对象:</p>
//emp整个对象
<p th:text="${emp}"></p>
//拿到对象emp内getId方法的返回值,下同
<p th:text="${emp.id}"></p>
<p th:text="${emp,name}"></p>
<p th:text="${emp.gender}"></p>
<p th:text="${emp.salary}"></p>
<p th:text="${emp.value}"></p>

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

6.8.2 稍微复杂的对象

案例:创建一个Employee002类,但是Employee02类中将一个Computer类作为自己的成员属性,在请求域内共享Employee002类的对象emp02,rootServlet调用Thymeleaf渲染root.html并响应给客户端,root.html要显示动态数据(请求域内的稍微复杂的对象emp02)

代码演示如下:

//创建Employee02类
public class Employee02 {private Integer id;private String name;private Integer gender; //0 男  1 女private Double salary;private Computer computer;//对象关联public Employee02(Integer id, String name, Integer gender, Double salary, Computer computer) {this.id = id;this.name = name;this.gender = gender;this.salary = salary;this.computer = computer;}public Employee02() {}@Overridepublic String toString() {return "Employee02{" +"id=" + id +", name='" + name + '\\'' +", gender=" + gender +", salary=" + salary +", computer=" + computer +'}';}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getGender() {return gender;}public void setGender(Integer gender) {this.gender = gender;}public Double getSalary() {return salary;}public void setSalary(Double salary) {this.salary = salary;}public Computer getComputer() {return computer;}public void setComputer(Computer computer) {this.computer = computer;}
}
//创建Computer类 
public class Computer {private Integer id;private String brand;private double price;public Computer() {}@Overridepublic String toString() {return "Computer{" +"id=" + id +", brand='" + brand + '\\'' +", price=" + price +'}';}public Computer(Integer id, String brand, double price) {this.id = id;this.brand = brand;this.price = price;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getBrand() {return brand;}public void setBrand(String brand) {this.brand = brand;}public double getPrice() {return price;}public void setPrice(double price) {this.price = price;}
}
//在rootServle中创建一个employee02对象,渲染root.html后响应给客户端
Employee02 employee02=new Employee02(102,"熊二"1,34567d,new Computer(1,"联想",5000.0)
//请求域内共享一个稍微复杂的对象
request.setAttribute("emp02",employee02);
//调用Thymeleaf渲染root.html页面,响应给客户端this.processTemplate("root",request,response);
//root.html获取请求域内emp02的相关属性
复杂对象:
<div th:text="${emp02}"></div>
<div th:text="${emp02.id}"></div>
<div th:text="${emp02.name}"></div>
<div th:text="${emp02.salary}"></div>
Kdiv th:text="${emp02.computer}"></div>
//调用的是emp02的电脑对象的getId()的返回值,下同
<div th:text="{emp02.computer.id}"></div>
<div th:text="$emp02.computer.brand}"></div>
<div th:text="$empe2.computer.price}"></div>

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

6.8.3 list集合(简单集合)

案例:在请求域内共享list集合,rootServlet调用Thymeleaf渲染root.html网页并响应给客户端,root.html要显示动态数据(请求域内的list集合)

代码演示如下:

//请求域内共享一个list集合
List<String> strs=new ArrayList<>();
strs.add("法外狂徒张三");
strs.add("法外狂徒李四");
strs.add("法外狂徒王五");
request.setAttribute("strs",strs);
//调用Thymeleaf渲染root.html并响应给客户端
this.processTemplate("root",request,response);
<p>list集合</p>
<p th:text="${strs}"></p>
//从请求域中获取list集合strs中下标为0的元素(第0+1个元素),下同
<p th:text="${strs[0]}"></p>
<p th:text="${strs[1]}"></p>
<p th:text="${strs[2]}"></p>

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

6.8.4 复杂集合(list集合存储对象)

案例:在请求域内共享复杂集合,集合内放三个Employee类的对象,rootServlet调用Thymeleaf渲染root.html,在root.html中要显示动态数据(请求域内的复杂集合)

代码示例如下:

//请求域内共享复杂集合
List<Employee> emps=new ArrayList<>();
emps.add(new Employee(101,"法外狂徒张三",0,500000.0));
emps.add(new Employee(102,"法外狂徒李四",1,68787.0));
emps.add(new Employee(103,"法外狂徒王五",1,198687.0));
request.setAttribute("emps",emps);
//调用Thymeleaf渲染root.html并响应给客户端
this.processTemplate("root",request,response);
<p>复杂集合</p>
<p th:text="${emps}"></p>
//获取集合中第一个对象的toString()的返回值
<p th:text="${emps[0]}"></p>
//获取集合中第一个对象的getId()的返回值
<p th:text="${emps[0].id}"></p>
//获取集合中第一个对象的getName()的返回值
<p th:text="${emps[0].name}"></p>

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

总结:

遇到对象就通过.属性名的方式去获取属性值(原理是调用get方法)
遇到Lst集合就通过下标获得到元素,如果元素是对象的话,还是回到上一句

6.8.5 复杂集合(map集合存储对象)

遇到Map集合就通过.key值的方式获得value值,如果value值是对象的话,遇到对象就通过.属性名的方式去获取属性值(原理是调用get方法)

案例:请求域内共享map集合,rootServlet调用Thymeleaf渲染root.html后响应给客户端,root.html要显示动态数据(请求域内的map集合)

代码示例如下:

//请求域内共享map集合
Map<String,Employee> map=new HashMap<>();
map.put("emp01",new Employee(101,"法外狂徒张三",0,500000.0));
map.put("emp02",new Employee(102,"法外狂徒李四",1,68787.0));
map.put("emp03",new Employee(103,"法外狂徒王五",1,198687.0));
request.setAttribute("map",map);
//调用Thymeleaf渲染root.html并响应给客户端
this.processTemplate("root",request,response);
<p>map集合</p>
<p th:text="${map}"></p>
//获取请求域内map集合的key值为emp01的value值
<p th:text="${map.emp01}"></p>
//获取请求域内map集合的key值为emp01的value值(对象)的getId()的返回值,下同
<p th:text="${map.emp01.id}"></p>
<p th:text="${map.emp02.name}"></p>

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

6.9 分支与迭代

6.9.1 分支,控制元素的是否显示

6.9.1.1 th:if 和 th:unless

语法:

th:if="" : 值如果是true,元素就显示,值如果是false,就不显示
th:unless="" : 和if反过来即可

案例:请求域内共享msg数据,调用Thymeleaf渲染页面并呼应给客户端,页面内使用h:if
或th:unless等渲染表达式去判断msg数据的长度

代码示例如下:

//在请求域中共享msg数据   request.setAttribute("msg","这是msg数据");this.processTemplate("toif",request,response);
<p>th:if/unless</p>
<p th:text="${msg}"></p>
<p th:if="${#strings.length(msg)>5}">msg的数据长度大于5就显示</p>
<p th:if="${#strings.length(msg)<=5}">msg的数据长度小于或等于5就显示(1)</p>
<p th:unless="${#strings.length(msg)>5}">msg的数据长度小于或等于5就显示(2)</p>
<p th:unless="${not (#strings.length(msg)<=5)}">msg的数据长度小于或等于5就显示(3)</p>

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

6.9.1.2 th:switch和th:case

语法:

th:switch=“” (看switch中的数据和哪个case相同,有相同的就显示哪个)
th:case=“”

案例:请求域内共享msg数据,调用Thymeleaf渲染页面并呼应给客户端,页面内使用渲染表达式th:switch和th:case去判断msg数据的长度并显示结果

代码示例如下:

request.setAttribute("msg","这是msg");
this.processTemplate("toif",request,response);
<div th:switch="${#strings.length(msg)}"><p th:case="1">长度为1</p><p th:case="2">长度为2</p><p th:case="3">长度为3</p><p th:case="4">长度为4</p><p th:case="5">长度为5</p>
</div>

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

6.9.2 迭代(遍历循环)

语法:

th:each=“obj,status:后台请求域中数据的key”

6.9.2.1 简单数组迭代

案例:请求域内共享一个list集合,调用thymeleaf渲染页面并响应给客户端,页面使用渲染表达式th:each去遍历请求域内list集合,在无序列表中显示

代码示例如下:

//请求域内共享一个list集合
List<String> strs=new ArrayList<>();
strs.add("法外狂徒张三");
strs.add("法外狂徒李四");
strs.add("法外狂徒王五");
request.setAttribute("strs",strs);
//迭代从请求域获得的list集合strs,并在无序列表中显示
<ul><li th:each="str,status :${strs}" th:text="${str}"></li>

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

6.9.2.2 复杂数组迭代

案例:请求域内共享一个list集合(装三个Employee类的对象),调用thymeleaf渲染页面并响应给客户端,页面使用渲染表达式th:each去遍历请求域内的list集合,在表格中显示

//请求域内共享复杂集合
List<Employee> emps=new ArrayList<>();
emps.add(new Employee(101,"法外狂徒张三",0,500000.0));
emps.add(new Employee(102,"法外狂徒李四",1,68787.0));
emps.add(new Employee(103,"法外狂徒王五",1,198687.0));
request.setAttribute("emps",emps);
<table border="1" width="300px"><tr><td>序号</td><th>编号</th><th>姓名</th><th>性别</th><th>工资</th></tr><tr th:each="emp,status :${emps}"><!--  status.index是从0开始的      --><td th:text="${status.index+1}"></td><td th:text="${emp.id}"></td><td th:text="${emp.name}"></td><!--  <td th:if="${emp.gender==0}" th:text="男"></td><td th:if="${emp.gender==1}" th:text="女"></td>--><td th:text="${emp.gender==0?'':''}"></td><td th:text="${emp.salary}"></td></tr>
</table>

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

6.10 Thymeleaf包含其他模板文件

6.10.1 应用场景

网页内公共代码片段的提取

公共代码片段是什么?

以腾讯视频 pc端为例,无论用户点击了什么频道,网站左侧的红框部分总是在那里,不会改变

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

6.10.2 操作步骤

①给公共的代码片段起个名字

使用th:fragment来给这个片段命名:

样例代码如下:

<div th:fragment="abc"id="header">公共头部信息</div>

我给上述公共的代码片段命名为abc

②在其他页面根据名字引用

有三种写法,但实现的最终效果都相同

a. th:replace

效果将引入标签整体替换目标标签

特点它不会保留页面自身的标签

样例代码如下:

<div th:replace="base::abc"id="ahcden "></div>

它使用了 th:replace 属性来替换当前标签,其值为 base::abc 表示使用名为 abc 的模板作为替换内容。其中 base 是模板的前缀或命名空间,通常与模板所在的文件夹或包名相关联。此外,这个标签也有一个 id 属性,其值为 “ahcden”。

用通俗的话来讲,找存放公共代码片段的页面(base.html),在页面里找名称为abc的公共代码片段,将公共代码片段所在的标签替换使用th:replace的标签

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

b. th:insert

效果将引入标签插入到目标标签内

特点它会保留页面自身的标签

样例代码如下:

<div th:insert="base::abc"id="aheader"></div>

找存放公共代码片段的页面(base.html),在页面里找名称为abc的公共代码片段,将公共代码片段所在的标签引入到使用th:replace的标签内

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

c. th:include

效果将引入标签内容插入到目标标签内

特点它会去掉片段外层标记,同时保留页面自身标记

样例代码如下:

<div th:include="base::abc"id="aheader"></div>

找存放公共代码片段的页面(base.html),在页面里找名称为abc的公共代码片段,将公共代码片段所在的标签,去掉外层的标签将内容引入到使用th:replace的标签内

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

6.10.3 综合案例

案例需求:创建四个html(a,b,c,abc),其中abc.html放前三个html都要用到的公共代码片段,剩余三个html的内容自定义。三个html均需在首页(index.html)通过超链接访问对应的servlet,再由各自对应的servlet穿给thymeleaf渲染对应的html文件,最后响应给客户端

1.创建三个html(a,b和c)对应的servlet(AServlet,BServlet和CServlet),并在web-xml中设置对应Servlet的访问路径

代码演示如下:

//在web-xml中设置对应Servlet的访问路径
<!-- 设置访问AServlet的路径  /a -->
<servlet><servlet-name>AServlet</servlet-name><servlet-class>Servlet.AServlet</servlet-class>
</servlet>
<servlet-mapping><servlet-name>AServlet</servlet-name><url-pattern>/a</url-pattern>
</servlet-mapping><!-- 设置访问BServlet的路径 /b -->
<servlet><servlet-name>BServlet</servlet-name><servlet-class>Servlet.BServlet</servlet-class>
</servlet><servlet-mapping><servlet-name>BServlet</servlet-name><url-pattern>/b</url-pattern>
</servlet-mapping><!-- 设置访问CServlet的路径 /c -->
<servlet><servlet-name>CServlet</servlet-name><servlet-class>Servlet.CServlet</servlet-class>
</servlet>
<servlet-mapping><servlet-name>CServlet</servlet-name><url-pattern>/c</url-pattern>
</servlet-mapping>
//创建a.html对应的AServlet
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;public class AServlet extends ViewBaseServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.processTemplate("a",request,response);}
}
//创建b.html对应的BServlet
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;public class BServlet extends ViewBaseServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.processTemplate("b",request,response);}
}
//创建c.html对应的CServlet
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;public class CServlet extends ViewBaseServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.processTemplate("c",request,response);}
}

2.在首页(index.html)中设立访问AServlet,BServlet,CServlet的超链接,并创建abc,a,b和c.html

//在index.html中设立访问AServlet,BServlet,CServlet的超链接
<a href="a">访问AServlet</a><br>
<a href="b">访问BServlet</a><br>
<a href="c">访问CServlet</a>
//创建abc.html,它存放的是a,b和c.html都要用的公共代码片段
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><base th:href="@{/}"><meta charset="UTF-8"><title>Title</title>
</head>
<body><div th:fragment="base" id="header">公共头部信息</div>
</body>
</html>
//创建a.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><base th:href="@{/}"><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<div th:include="abc::base" id="aheader"></div>
<h1>a</h1>
</body>
</html>
//创建b.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><base th:href="@{/}"><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<div th:include="abc::base" id="bheader"></div>
<h1>b</h1>
</body>
</html>
//创建c.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><base th:href="@{/}"><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<div th:include="abc::base" id="cheader"></div>
<h1>c</h1>
</body>
</html>

3.测试代码

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?

如何使用Thymeleaf给web项目中的网页渲染显示动态数据?
如何使用Thymeleaf给web项目中的网页渲染显示动态数据?