Bootstrap

Thymeleaf快速入门【基础总结】

Thymeleaf

一、Thymeleaf入门

1. Thymeleaf简介

1.1. 为什么需要Thymeleaf ?

在这里插入图片描述

  1. 如上图所示, 当用servlet实现动态页面展示的时候,虽然我们可以用writer.write()写出整个页面,以展示动态信息,

​ 但是代码实在是太冗长,根本无法维护,所以需要将视图展示抽取出来,单独作为一个View视图层。

  1. 如果只使用HTML作为视图的话,它是无法展示动态数据的,所以我们对HTML产生了新的需求:既能够正常显示页面,又能在页面中包含动态数据部分。而动态数据单靠HTML本身是无法做到的,所以此时需要引入服务器端动态视图模板技术,如Thymeleaf

1.2. Thymeleaf介绍

Thymeleaf是一款用于渲染XML/XHTML/HTML5内容的模板引擎。类似的模板引擎还有 JSPVelocityFreeMarker等, 它们也可以轻易的与Spring MVC等Web框架进行集成并作为Web应用的模板引擎。

模板引擎的主要作用是在静态页面上渲染显示动态数据


Thymeleaf的优势

  • 是SpringBoot官方推荐使用的视图模板技术,和SpringBoot完美整合。

  • 不经过服务器运算仍然可以直接查看原始值,对前端工程师更友好。

1.3. Thymeleaf的视图(物理视图和逻辑视图)

物理视图

什么是物理视图?

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

如: /pages/user/login_success.html

如果把所有的HTML页面都放在某个统一的目录下,那么转发地址就会呈现出明显的规律:

/pages/user/login.html
/pages/user/login_success.html
/pages/user/regist.html
/pages/user/regist_success.html

……

路径的开头都是:/pages/user/

路径的结尾都是:.html

所以,路径开头的部分称之为视图前缀,路径结尾的部分称之为视图后缀。


逻辑视图

什么是逻辑视图?

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

在上面的例子中:

视图前缀逻辑视图视图后缀物理视图
/pages/user/login.html/pages/user/login.html
/pages/user/login_success.html/pages/user/login_success.html

二、Thymeleaf基本语法

1. th名称空间

: 如果是thymeleaf的模板html文件,在html标签内要加入Thymeleaf的th名称空间的声明,否则模板文件不生效。如下所示:

在这里插入图片描述

2. 表达式语法

2.1. 修改标签文本值

代码:

<p th:text="标签体新值">标签体原始值</p>

示例:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>目标页面</title>
</head>
<body>
    <!--th:text="${username}"表示在当前p标签的标签体里面显示服务器中的一个username的数据-->
	<p th:text="${username}">username</p>
</body>
</html>

th:text作用:

  • 不经过服务器解析,直接用浏览器打开HTML文件,看到的是『标签体原始值』
  • 经过服务器解析,Thymeleaf引擎根据th:text属性指定的『标签体新值』去替换『标签体原始值』

2.2. 修改指定属性值

代码:

<input type="text" name="username" th:value="文本框新值" value="文本框旧值" />

示例:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>目标页面</title>
</head>
<body>
<input type="text" name="username" th:value="${username}" value="username" />
</body>
</html>

语法:任何HTML标签原有的属性,前面加上『th:』就都可以通过Thymeleaf来设定新值。


2.3. 解析URL地址

代码:

<!--
使用Thymeleaf解析url地址
-->
<a th:href="@{/index.html}">访问index.html</a>

示例:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>目标页面</title>
</head>
<body>
<a href="/thymeleaf_learn/index.html" th:href="@{/index.html}">访问index.html</a>
</body>
</html>

经过解析后得到:

/thymeleaf_learn/index.html

所以@{/}的作用是在字符串前附加『上下文路径』

这个语法的好处是:实际开发过程中,项目在不同环境部署时,Web应用的名字有可能发生变化。所以上下文路径不能写死。而通过@{/} 动态获取上下文路径后,不管怎么变都不怕啦!

2.4. 解析携带参数的URL地址

代码:

<!--
使用Thymeleaf解析url地址,格式如下:
-->
<a th:href="@{/index.html(参数名=${动态数据},参数名='静态数据')}">访问index.html</a>

示例:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>目标页面</title>
</head>
<body>
<a th:href="@{/index.html(username=${username},password='123456')}">访问index.html</a>
</body>
</html>

2.5. 显示动态的首页

首页地址使用URL地址解析

一般项目启动后,默认访问的页面是位于项目目录下的index.html:

在这里插入图片描述

同时我们也可以在浏览器中直接访问index.html本身,那么index.html是不需要通过Servlet,当然也不经过模板引擎,所以index.html上的Thymeleaf的任何表达式都不会被解析。

目前访问主页的效果, 如下图所示:

在这里插入图片描述

解决办法

  1. 通过Servlet访问index.html,这样就可以让模板引擎渲染页面了.
    1. 需要在view文件夹中建立一个新的模板文件作为首页,并为之建立一个Servlet,然后在web.xml配置文件中注册这个Servlet.
    2. 最后修改默认的欢迎界面配置为默认去访问这个Servlet即可。

而通过使用Servlet+Thymeleaf更改和动态解析首页地址,现在访问主页的效果如下:

在这里插入图片描述

进一步的好处:

通过上面的例子我们看到,所有和业务功能相关的请求都能够确保它们通过Servlet来处理,这样就方便我们统一对这些请求进行特定规则的限定。

具体操作步骤如下:

第一步,在view文件夹中创建一个新的动态首页hello.html:

在这里插入图片描述

hello.html

<!DOCTYPE html>
<!--注意模板文件的html标签需要加上thymeleaf的th名称空间的声明语句-->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
    
<head>
    <meta charset="UTF-8">
    <title>动态index页面</title>
</head>
    
<body>
<p th:text="${value}">value</p>
</body>
</html>

第二步,servlet目录下创建一个Servlet文件: IndexThymeleafServlet:

ViewBaseServlet

package com.carson.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

//类继承处理模板文件的ViewBaseServlet
public class IndexThymeleafServlet extends ViewBaseServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //在请求域中插入数据,属性名:value,属性值: I am a dynamic index page.
        req.setAttribute("value","I am a dynamic index page.");
        //请求转发跳转到/WEB-INF/view/hello.html
        processTemplate("hello",req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

第三步,修改web.xml注册Servlet, 并把默认的首页指向servlet:

<!-- 更改指向首页的Servlet -->
    <!--注册indexThymeleafServlet以及配置映射路径-->
    <servlet>
        <servlet-name>indexThymeleafServlet</servlet-name>
        <servlet-class>com.carson.servlet.IndexThymeleafServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>indexThymeleafServlet</servlet-name>
        <url-pattern>/indexThymeleaf</url-pattern>
    </servlet-mapping>
    
    <!-- 把首页指向IndexThymeleafServlet -->
    <welcome-file-list>
        <welcome-file>indexThymeleaf</welcome-file>
    </welcome-file-list>

最后启动Tomcat测试: 发现默认访问的不是index.html了,而是hello.html

在这里插入图片描述


2.6. 域对象在Thymeleaf中的使用

2.6.1 什么是域对象

域对象是在服务器中有一定作用域范围的对象,在这个范围内的所有动态资源都能够共享域对象中保存的数据。

请求域request

在请求转发的场景下,我们可以借助HttpServletRequest对象内部给我们提供的存储空间,帮助我们携带数据,把数据发送给转发的目标资源。

请求域:HttpServletRequest对象内部给我们提供的存储空间

会话域session

会话域的范围是一次会话.

会话: 用户打开一个浏览器,访问多个web资源,关闭浏览器,这个过程称之为一个会话。

在这里插入图片描述

应用域application

应用域的范围是整个项目全局, 也就是ServletContext对象, 其凌驾于各个Servlet之上。

在这里插入图片描述

在这里插入图片描述

2.6.2. 在Thymeleaf中操作域对象

我们通常的做法是,在Servlet中将数据存储到域对象中,而在使用了Thymeleaf的前端页面中取出域对象中的数据进行展示。

操作请求域

Servlet中代码:

String requestAttrName = "helloRequestAttr";
String requestAttrValue = "helloRequestAttr-VALUE";

request.setAttribute(requestAttrName, requestAttrValue);

Thymeleaf表达式:

<p th:text="${helloRequestAttr}">request field value</p>
操作会话域

Servlet中代码:

// ①通过request对象获取session对象
HttpSession session = request.getSession();

// ②存入数据
session.setAttribute("helloSessionAttr", "helloSessionAttr-VALUE");

Thymeleaf表达式:

<p th:text="${session.helloSessionAttr}">这里显示会话域数据</p>
操作应用域

Servlet中代码:

// ①通过调用父类的方法获取ServletContext对象
ServletContext servletContext = getServletContext();

// ②存入数据
servletContext.setAttribute("helloAppAttr", "helloAppAttr-VALUE");

Thymeleaf表达式:

<p th:text="${application.helloAppAttr}">这里显示应用域数据</p>

2.7. 获取请求参数

当一个带参数的链接指向一个Servlet,那么该Servlet该如何获取参数,并显示到Thymeleaf的页面中呢?

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

代码:

<p th:text="${param.username}">这里替换为请求参数的值</p>

示例:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>目标页面</title>
</head>
<body>
<p th:text="${param.username}">这里替换为请求参数的值</p>
</body>
</html>

页面显示效果:

在这里插入图片描述

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

代码:

<p th:text="${param.team}">这里替换为请求参数的值</p>

页面显示效果:

如果想要精确获取某一个值,可以使用数组下标。页面代码:

<p th:text="${param.team[0]}">这里替换为请求参数的值</p>
<p th:text="${param.team[1]}">这里替换为请求参数的值</p>

页面显示效果:

在这里插入图片描述

2.8. 内置对象

所谓内置对象其实就是在Thymeleaf的表达式中可以直接使用的对象。

基本内置对象

在这里插入图片描述

用法举例:

<h3>表达式的基本内置对象</h3>
<p th:text="${#request.getContextPath()}">调用#request对象的getContextPath()方法</p>
<p th:text="${#request.getAttribute('helloRequestAttr')}">调用#request对象的getAttribute()方法,读取属性域</p>

基本思路:

  • 如果不清楚这个对象有哪些方法可以使用,那么就通过getClass().getName()获取全类名,再回到Java环境查看这个对象有哪些方法
  • 内置对象的方法可以直接调用
  • 调用方法时需要传参的也可以直接传入参数
公共内置对象

在这里插入图片描述

Servlet中将List集合数据存入请求域:

request.setAttribute("aNotEmptyList", Arrays.asList("aaa","bbb","ccc"));
request.setAttribute("anEmptyList", new ArrayList<>());

模板页面代码:

<p>#list对象isEmpty方法判断集合整体是否为空aNotEmptyList:<span th:text="${#lists.isEmpty(aNotEmptyList)}">测试#lists</span></p>
<p>#list对象isEmpty方法判断集合整体是否为空anEmptyList:<span th:text="${#lists.isEmpty(anEmptyList)}">测试#lists</span></p>

公共内置对象对应的源码位置:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kL4dq6mE-1637327086119)(imgs/image20.png)]

2.9. 分支与迭代

2.9.1 if 和unless分支

标记了th:if、th:unless的标签会根据条件决定是否显示标签。

th:if 如果值为true 则显示出该标签 否则 不显示(隐藏)

th:unless则和th:if 相反

示例的Servlet代码:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    //往request域对象中存储List集合
    request.setAttribute("aNotEmptyList", Arrays.asList("aaa","bbb","ccc"));
    request.setAttribute("anEmptyList", new ArrayList<>());

    //调用方法渲染视图
    processTemplate("list", request, response);
}

示例的HTML代码:

list.html

<!--
使用Thymeleaf的th:if和th:unless来控制标签的显示与否
-->
<p th:unless="${#lists.isEmpty(aNotEmptyList)}">anNotEmptyList中有数据</p>
<p th:if="${#lists.isEmpty(aNotEmptyList)}">anNotEmptyList中没有数据</p>

<p th:unless="${#lists.isEmpty(anEmptyList)}">anEmptyList中有数据</p>
<p th:if="${#lists.isEmpty(anEmptyList)}">anEmptyList中没有数据</p>
2.9.2. switch分支
  1. th:switch 和 th:case 与 Java 中的 switch 语句等效,会有条件地显示匹配的内容。

  2. 只要其中⼀个 th:case 的值为 true就显示标签,则同⼀个 switch 语句中的其他 th:case 属性都将被视为 false即都不显示标签。

示例的Servlet代码:

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //往request域对象中存储名为level的数据,测试数据值:level2
        req.setAttribute("level","level2");
        //调用方法渲染视图
        processTemplate("list", req, resp);
    }

示例的HTML代码:

list.html

<h3>测试switch</h3>
<div th:switch="${level}">
    <p th:case="level1">银牌会员</p>
    <p th:case="level2">金牌会员</p>
    <p th:case="level3">白金会员</p>
    <p th:case="level4">钻石会员</p>
</div>
2.9.3. each循环

示例的Servlet代码:

@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //往request域对象中存储List集合
        req.setAttribute("userList", Arrays.asList("aaa","bbb","ccc","ddd"));
        //调用方法渲染视图
        processTemplate("each", req, resp);
    }

示例的HTML代码:

each.html

<!DOCTYPE html>

<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>用户列表展示页面</title>
</head>
<body>

<!--
    获取域对象中的集合,并且遍历展示
-->
<table border="1" cellspacing="0" width="400" align="center">
    <thead>
    <tr>
        <th>下标</th>
        <th>奇数</th>
        <th>具体值</th>
    </tr>
    </thead>


    <tbody th:if="${#lists.isEmpty(userList)}">
    <tr>
        <td colspan="3">用户信息为空,没法遍历展示数据</td>
    </tr>


    </tbody>
    <tbody th:unless="${#lists.isEmpty(userList)}">
    <!--
    使用th:each进行遍历迭代
        1. th:each写在哪? 每遍历出一条数据就要添加一个什么标签就写在什么标签上,这里以写在tr标签示例
        2. th:each="遍历出来的数据 : 要遍历的数据"
        3. 我们怎么使用遍历出来的数据: ${遍历出来的数据}

        使用格式:  th:each="遍历出来的数据,遍历出来的数据的状态 : 要遍历的数据"
        遍历出来的数据的状态又包含:
            index表示下标
            count表示计数
            even表示是否是偶数
            odd表示是否是奇数
            current表示遍历出来的当前元素
            first表示第一个元素
            last表示最后一个元素
        例如: 下标
    -->
    <tr th:each="user,status : ${userList}">
        <td th:text="${status.index}"></td>
        <td th:text="${status.odd}"></td>
        <td th:text="${status.current}"></td>
    </tr>
    </tbody>
</table>
</body>
</html>

2.10. Thymeleaf包含其他模板文件

应用场景

抽取各个页面的公共部分,类似VUE的组件:

在这里插入图片描述

demo操作步骤

第一步,创建一个模板文件segment.html ,并在其中创建页面的公共代码片段:

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

<!--使用  th:fragment  来给这个片段命名:-->
<div th:fragment="header">
    <p>被抽取出来的头部内容</p>
</div>

segment.html

<!DOCTYPE html>

<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>segment demo</title>
</head>

<body>
    <!--创建页面的公共代码片段-->
    <div th:fragment="header">
        <p>被抽取出来的头部内容</p>
    </div>

</body>
</html>

第二步,在需要的模板页面中进行包含:

使用格式: 代码片段所在页面的逻辑视图 :: 代码片段的名称

语法效果特点
th:insert把目标的代码片段整个插入到当前标签内部它会保留页面自身的标签
th:replace用目标的代码替换当前标签它不会保留页面自身的标签
th:include把目标的代码片段去除最外层标签,然后再插入到当前标签内部它会去掉片段外层标记,同时保留页面自身标记

在需要的模板页面中包含公共代码片段,测试的主要代码如下:

<!-- 代码片段所在页面的逻辑视图 :: 代码片段的名称 -->
<div id="insertDiv" th:insert="segment :: header">
    div标签的原始内容
</div>

<div id="replaceDiv" th:replace="segment :: header">
    div标签的原始内容
</div>

<div id="includeDiv" th:include="segment :: header">
    div标签的原始内容
</div>

最后启动Tomcat测试:

在这里插入图片描述

查看页面的HTML代码,观察不同语法的差别:

在这里插入图片描述

语法效果特点
th:insert把目标的代码片段整个插入到当前标签内部它会保留页面自身的标签
th:replace用目标的代码替换当前标签它不会保留页面自身的标签
th:include把目标的代码片段去除最外层标签,然后再插入到当前标签内部它会去掉片段外层标记,同时保留页面自身标记
  • th: insert方法会保留自身的标签, 即体现为页面原来的<div id="insertDiv">标签还会保留!!
  • th: replace方法不会保留自身的标签, 即体现为页面原来的<div id="replaceDiv">标签没有被保留!!
  • th: include方法会去掉片段的外层标记,同时保留页面自身标记。即体现为页面原来的<div id="includeDiv"标签有保留,但是原来声明公共代码片段的外部标签 <div th:fragment="header">没有被保留!!

2.11 字符串拼接

字符串连接有两种方式 :

  • 通过 ’ ’ 和 + 拼接字符串 ;
  • | | 拼接字符串(推荐);

:

<!-- 通过 '' 和 + 拼接字符串 -->
<div th:text="'哈哈,'+${hello}+','+${name}+'!'" ></div>

----------------------------------

<!-- 通过 | | 拼接字符串(推荐) -->
<div th:text="|哈哈,${hello},${name}!|" ></div>

三 Thymeleaf的实践案例

第一步,加入jar包:

在这里插入图片描述

第二步,在web.xml文件中配置上下文参数属性值,后续servlet需要读取:

<!-- 在web.xml文件中的上下文参数中配置视图前缀和视图后缀的相关属性和值,方便后续servlet读取 -->
<!-- 说明:param-value中设置的前缀、后缀的值不是必须叫这个名字,可以根据实际情况和需求进行修改。
	这里示例将用于视图前缀设置为: /WEB-INF/view/, 视图后缀设置为: .html -->
	
<context-param>
    <param-name>view-prefix</param-name>e
    <param-value>/WEB-INF/view/</param-value>
</context-param>
<context-param>
    <param-name>view-suffix</param-name>
    <param-value>.html</param-value>
</context-param>

为什么视图模板文件要设置放在WEB-INF目录下?

原因

  1. 位于WEB-INF目录下的文件是不允许浏览器直接访问的,所以我们的视图模板文件放在这个目录下,是一种保护。以免外界可以随意访问视图模板文件。

  2. 访问WEB-INF目录下的页面,都必须通过Servlet转发过来,简单说就是:不经过Servlet访问不了, 这样就方便我们在Servlet中检查当前用户是否有权限访问。


当放在WEB-INF目录下之后,里面的文件重定向进不去怎么办?

解决方案: 将请求重定向到Servlet中,再通过Servlet转发到WEB-INF下。

第三步,在src相关目录下创建处理模板文件的Servlet基类:如: src.com.carson.sevlet目录

这个类直接复制粘贴即可,将来使用框架后,这些代码都将被取代。

package com.carson.servlet;

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;

    //重写init()方法(其是servlet的初始化方法)
    @Override
    public void init() throws ServletException {
        //1. 获取当前Servlet的ServletContext对象
        ServletContext servletContext = this.getServletContext();
        //2. 创建Thymeleaf解析器对象,其接收:一个ServletContext对象
        ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(servletContext);
        //3. 给解析器对象设置参数
          //3.1 设置解析的模板模式, HTML是默认模式,明确设置是为了代码更容易理解
        templateResolver.setTemplateMode(TemplateMode.HTML);
          //3.2 设置前缀
        String viewPrefix = servletContext.getInitParameter("view-prefix");
        templateResolver.setPrefix(viewPrefix);
          //3.3 设置后缀
        String viewSuffix = servletContext.getInitParameter("view-suffix");
        templateResolver.setSuffix(viewSuffix);
          //3.4 设置缓存过期时间(毫秒)
        templateResolver.setCacheTTLMs(60000L);
          //3.5 设置是否缓存
        templateResolver.setCacheable(true);
          //3.6 设置服务器端编码方式
        templateResolver.setCharacterEncoding("utf-8");

        //4. 实例化模板引擎对象
        templateEngine = new TemplateEngine();

        //5. 给模板引擎对象设置模板解析器对象
        templateEngine.setTemplateResolver(templateResolver);
    }

    //创建处理模板文件的函数
    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());
    }
}

第四步:在Tomcat中配置项目启动路径,这里我设置为:thymeleaf_learn

在这里插入图片描述

第五步,在WEB-INF目录下创建index.html文件:

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>测试ThymeLeaf Demo</title>
</head>

<body>
    <!--注意:这里href跳转链接的书写前面需要加上项目启动路径:在这里是/thymeleaf_learn  -->
    <a href="/thymeleaf_learn/testThymeleaf">Carson初步测试Thymeleaf!</a>
</body>
</html>

第六步,在servlet目录下创建测试的TestThymeleafServlet,并在web.xml中进行注册

TestThymeleafServlet

package com.carson.servlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;

//类继承处理模板的基础类
public class TestThymeleafServlet extends ViewBaseServlet{
    //重写doGet和doPost等方法
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //请求域中存储数据
        req.setAttribute("username","Welcome to Carson's Target Html!");
        req.setAttribute("requestData","这是请求域中存储的数据!");

        req.setAttribute("aNotEmptyList", Arrays.asList("aaa","bbb","ccc"));
        req.setAttribute("anEmptyList", new ArrayList<>());

        //会话域中存储数据
        HttpSession session = req.getSession();
        session.setAttribute("sessionData","这是会话域中存储的数据!");
        //应用域中存储数据
        ServletContext servletContext = this.getServletContext();
        servletContext.setAttribute("applicationData","这是应用域中存储的数据!");
        
        //请求转发跳转到/WEB-INF/view/target.html
        //调用父类的processTemplate方法
        processTemplate("target",req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

web.xml中

	<!--注册testThymeleafServlet以及配置映射路径-->
    <servlet>
        <servlet-name>testThymeleafServlet</servlet-name>
        <servlet-class>com.carson.servlet.TestThymeleafServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>testThymeleafServlet</servlet-name>
        <url-pattern>/testThymeleaf</url-pattern>
    </servlet-mapping>

第七步,在WEB-INF/view目录下编写Thymeleaf模板文件代码:target.html

注: 在编写Thymeleaf的模板文件时,部分代码出现下划线报红?

答: 不用理会,因为模板文件未得到服务器端运行时是会报红的。

target.html

<!DOCTYPE html>

<!--注意:html作为模板文件时,html标签里面要加上xmlns:th="http://www.thymeleaf.org"-->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Target Html(目标页面)</title>
</head>

<body>
    <!--运用thymelaf语法,修改标签文本值-->
    <h1 th:text="${username}">未经过服务器解析前的HTML页面</h1>
    
    <!--运用thymelaf语法,修改标签指定属性值-->
    <input type="text" name="username" value="未更改前的value" th:value="${username}">
    
    <!--运用thymelaf语法,解析不带参数的URL地址
        原本是跳转到百度,现在通过thymeleaf解析URL跳转到本项目的主页-->
    <a href="http://www.baidu.com" th:href="@{/index.html}">点击跳转</a>
    
    <!--运用thymelaf语法,解析携带参数的URL地址-->
    <a th:href="@{/index.html(username=${username},password='123456')}">解析携带参数的URL</a>
    
    <!--显示三个级别的域对象中存储的数据信息-->
    <p th:text="${requestData}"></p>
    <p th:text="${session.sessionData}"></p>
    <p th:text="${application.applicationData}"></p>
    
    <!--Thymeleaf表达式的内置对象,内置对象要用#开头表示-->
    <h3>Thymeleaf表达式的基本内置对象的方法测试:</h3>
    <p th:text="${#request.getContextPath()}"></p>
    <p th:text="${#request.getAttribute('requestData')}"></p>
    <!--获取基本内置对象的全类名-->
    <p th:text="${#request.getClass().getName()}"></p>
    
    <!--Thymeleaf的公共内置对象测试-->
    <p>#lists对象isEmpty方法判断集合整体是否为空aNotEmptyList:<span th:text="${#lists.isEmpty(aNotEmptyList)}">测试#lists</span></p>
    <p>#lists对象isEmpty方法判断集合整体是否为空anEmptyList:<span th:text="${#lists.isEmpty(anEmptyList)}">测试#lists</span></p>
    <!--获取公共内置对象的全类名-->
    <p th:text="${#lists.getClass().getName()}"></p>

</body>
</html>

最后启动Tomcat进行测试:

在这里插入图片描述

在这里插入图片描述


The End!!创作不易,欢迎点赞/评论!!欢迎关注个人公众号

在这里插入图片描述

;