Springboot - Thymeleaf篇

本文详细介绍了Springboot集成Thymeleaf的使用,包括Thymeleaf的基本概念、入门案例、模板解析、表达式用法、条件判断、循环操作以及内联文本和内嵌变量的使用。Thymeleaf作为一个强大的模板引擎,提供了动静结合的特性,并与SpringBoot整合,简化了Web应用的开发。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Springboot - Thymeleaf



1. Thymeleaf

概念

  • Thymeleaf是一个跟FreeMarker类似的模板引擎,它可以完全替代 JSP 。相较与其他的模板引擎,它有如下特点:
    • 动静结合:Thymeleaf有网络和无网络的环境下皆可运行,无网络显示静态内容,有网络用后得到数据替换静态内容
    • 与SpringBoot完美整合,springboot默认整合thymeleaf

1.1 入门案例

实体类、Mapper文件同博文 - 整合mybatis案例

编写接口

  • 编写UserService,调用UserMapper的查询所有方法
/**
 * User - Service
 *
 * @author murphy
 */
@Service
public class UserService {

    @Resource
    private UserMapper userMapper;

    public List<User> findAll() {
        return userMapper.selectAll();
    }
    
}
  • 编写一个controller - 返回一些用户数据,放入模型中,等会在页面渲染
/**
 * User - Controller
 *
 * @author murphy
 */
@Controller
public class UserController {

    @Resource
    private UserService userService;

    @RequestMapping("all")
    public String all(Model model) {
        List<User> list = userService.findAll();
        model.addAttribute("users", list);
        // 跳转 - classpath:/templates/users.html
        return "users";
    }
    
}
  • 引入启动器 - 直接引入启动器:
<!-- thymeleaf -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

SpringBoot会自动为Thymeleaf注册一个视图解析器

在这里插入图片描述

与解析JSP的InternalViewResolver类似,Thymeleaf也会根据前缀后缀来确定模板文件的位置:

在这里插入图片描述

  • 默认前缀classpath:/templates/
  • 默认后缀.html

所以如果我们返回视图:users,会指向到classpath:/templates/users.html

一般我们无需进行修改,默认即可。

静态页面

根据上面的文档介绍,模板默认放在classpath下的templates文件夹,我们新建一个html文件放入其中:

在这里插入图片描述

编写html模板,渲染模型中的数据:

注意:把html的名称空间,改成xmlns:th="http://www.thymeleaf.org"会有语法提示

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
    <style type="text/css">
        table {
            border-collapse: collapse;
            font-size: 14px;
            width: 80%;
            margin: auto
        }

        table, th, td {
            border: 1px solid darkslategray;
            padding: 10px
        }
    </style>
</head>
<body>
<div style="text-align: center">
    <span style="color: darkslategray; font-size: 30px">欢迎光临!</span>
    <hr/>
    <table class="list">
        <tr>
            <th>id</th>
            <th>姓名</th>
            <th>用户名</th>
            <th>年龄</th>
            <th>性别</th>
            <th>生日</th>
            <th>备注</th>
            <th>操作</th>
        </tr>
        <tr th:each="user : ${users}">
            <td th:text="${user.id}">1</td>
            <td th:text="${user.name}">murphy</td>
            <td th:text="${user.userName}">张三</td>
            <td th:text="${user.age}">20</td>
            <td th:text="${user.sex} == 1 ? '': ''"></td>
            <td th:text="${#dates.format(user.birthday, 'yyyy-MM-dd')}">1980-02-30</td>
            <td th:text="${user.note}">1</td>
            <td>
                <a href="#">删除</a>
                <a href="#">修改</a>
                <a href="#">审核</a>
            </td>
        </tr>
    </table>
</div>
</body>
</html>

我们看到这里使用了以下语法

  • ${}:这个类似与el表达式,但其实是ognl的语法,比el表达式更加强大
  • th-指令:th-是利用了Html5中的自定义属性来实现的。如果不支持H5,可以用data-th-来代替
    • th:each:类似于c:foreach遍历集合,但是语法更加简洁
    • th:text:声明标签中的文本
      • 例如<td th-text='${user.id}'>1</td>,如果user.id有值,会覆盖默认的 1
      • 如果没有值,则会显示td中默认的1。这正是thymeleaf能够动静结合的原因,模板解析失败不影响,页面的显示效果,因为会显示默认值!

测试

接下来,我们打开页面测试一下:

在这里插入图片描述

模板缓存

Thymeleaf会在第一次对模板解析之后进行缓存,极大的提高了并发处理能力。但是这给我们开发带来了不便,修改页面后并不会立刻看到效果,我们开发阶段可以关掉缓存使用:

# 开发阶段关闭thymeleaf的模版缓存
spring.thymeleaf.cache=false

注意

  • 在IDEA中,我们需要在修改页面后按快捷键:Ctrl + Shift + F9对项目进行rebuild才可以。

1.2 thymeleaf 详解

表达式

它们分为三类:

  1. 变量表达式

  2. 选择或星号表达式

  3. URL表达式

变量表达式

  • 变量表达式即OGNL表达式或Spring EL表达式(在Spring中用来获取model attribute的数据)。如下所示:
${session.user.name}

它们将以HTML标签的一个属性来表示:

<h5>表达式</h5>
<span>${text}</span>
<span th:text="${text}">你好 thymleaf</span>

选择(星号)表达式

  • 选择表达式很像变量表达式,不过它们用一个预先选择的对象来代替上下文变量容器(map)来执行,如下:
*{customer.name}

被指定的objectth:object属性定义:

<tr th:each="user, status : ${users}" th:object="${user}" th:bgcolor="${status.even} ? 'gray'">
    <td th:text="${status.count}">1</td>
    <td th:text="*{id}">1</td>
    <td th:text="*{name}">murphy</td>
    <td th:text="*{userName}">张三</td>
    <td th:text="${user.age}">20</td>
    <td th:text="${user.sex} == 1 ? '': ''"></td>
    <td th:text="${#dates.format(user.birthday, 'yyyy-MM-dd')}">1980-02-30</td>
    <td th:text="${user.note}">1</td>
    <td>
        <a th:href="@{/delete(id=*{id},userName=*{userName})}">删除</a>
        <a th:href="|/update/${user.id}|">修改</a>
        <a th:href="'/approve/' + ${user.id}">审核</a>
    </td>
</tr>

URL表达式

  • URL表达式指的是把一个有用的上下文或回话信息添加到URL,这个过程经常被叫做URL重写@{/order/list}

URL还可以设置参数: @{/order/details(id=${orderId}, name=*{name})}

相对路径:@{../documents/report}

让我们看这些表达式:

<form th:action="@{/createOrder}">
<a href="main.html" th:href="@{/main}">

url表达式

<a th:href="@{/delete(id=${user.id}, userName=*{userName})}">删除</a>

文本替换

<a th:href="|/update/${user.id}|">修改</a>

字符串拼接

<a th:href="'/approve/' + ${user.id}">审核</a>

表达式常见用法

字面(Literals)

  • 文本文字(Text literals): 'one text', 'Another one!',...
  • 数字文本(Number literals): 0, 34, 3.0, 12.3,...
  • 布尔文本(Boolean literals): true, false
  • 空(Null literal): null
  • 文字标记(Literal tokens): one, sometext, main,...

文本操作(Text operations)

  • 字符串连接(String concatenation): +
  • 文本替换(Literal substitutions): |The name is ${name}|

算术运算(Arithmetic operations)

  • 二元运算符(Binary operators): +, -, *, /, %
  • 减号(单目运算符)Minus sign (unary operator): -

布尔操作(Boolean operations)

  • 二元运算符(Binary operators):and, or
  • 布尔否定(一元运算符)Boolean negation (unary operator):!, not

比较和等价(Comparisons and equality)

  • 比较(Comparators): >, <, >=, <= (gt, lt, ge, le)
  • 等值运算符(Equality operators):==, != (eq, ne)

条件运算符(Conditional operators)

If-then(if)? (then)

If-then-else(if)? (then) : (else)

Default(value) ?: (defaultvalue)

常用th标签

在这里插入图片描述

基本用法

  1. 赋值、字符串拼接

字符串拼接还有另外一种简洁的写法

<a th:href="|/update/${user.id}|">修改</a>
<a th:href="'/approve/' + ${user.id}">审核</a>
  1. 条件判断 If/Unless

Thymeleaf中使用th:ifth:unless属性进行条件判断,下面的例子中,<a>标签只有在th:if中条件成立时才显示:

<h5>if指令</h5>
<a th:if="${users.size() > 0}">查询结果存在</a>
<a th:if="${users.size() <= 0}">查询结果不存在</a>
<a th:unless="${session.user != null}" href="#">登录</a>

th:unlessth:if恰好相反,只有表达式中的条件不成立,才会显示其内容。

也可以使用(if)? (then) : (else)这种语法来判断显示的内容

  1. for 循环
<tr th:each="user, status : ${users}" th:object="${user}" th:bgcolor="${status.even} ? 'gray'">
    <td th:text="${status.count}">1</td>
    <td th:text="*{id}">1</td>
    <td th:text="*{name}">murphy</td>
    <td th:text="*{userName}">张三</td>
    <td th:text="${user.age}">20</td>
    <td th:text="${user.sex} == 1 ? '': ''"></td>
    <td th:text="${#dates.format(user.birthday, 'yyyy-MM-dd')}">1980-02-30</td>
    <td th:text="${user.note}">1</td>
    <td>
        <a th:href="@{/delete(id=*{id},userName=*{userName})}">删除</a>
        <a th:href="|/update/${user.id}|">修改</a>
        <a th:href="'/approve/' + ${user.id}">审核</a>
    </td>
</tr>

status称作状态变量,属性有:

  • index:当前迭代对象的index(从 0 开始计算)
  • count:当前迭代对象的index(从 1 开始计算)
  • size:被迭代对象的大小
  • current:当前迭代变量
  • even/odd:布尔值,当前循环是否是偶数/奇数(从 0 开始计算)
  • first:布尔值,当前循环是否是第一个
  • last:布尔值,当前循环是否是最后一个
  1. 内联文本
  • 内联文本:[[...]]内联文本的表示方式,使用时,必须先用th:inline="text/javascript/none"激活,th:inline可以在父级标签内使用,甚至作为body的标签。内联文本尽管比th:text的代码少,不利于原型显示。

thymeleaf指令中显示

<h6 th:text="${text}">静态内容</h6>

使用内联文本显示model attribute

<h5>内联文本</h5>
<span>[[${text}}]]</span><br>
<span th:inline="text">[[${text}}]]</span><br>
<span th:inline="none">[[${text}}]]</span><br>

原则能用指令就用th指令

  1. 内联JS
  • 内联文本:[[...]]内联文本的表示方式,使用时,必须先用th:inline="text/javascript/none"激活,th:inline可以在父级标签内使用,甚至作为body的标签。内联文本尽管比th:text的代码少,不利于原型显示。
<h5>内联js</h5>
<script th:inline="javascript">
    /*<![CDATA[*/
        var text = '[[${text}]]';
        alert(text);
    /*]]>*/
</script>
  1. 内嵌变量
  • 为了模板更加易用,Thymeleaf还提供了一系列Utility对象(内置于Context中),可以通过#直接访问
    • datesjava.util.Date**的功能方法类。
    • calendars:类似#dates,面向java.util.Calendar
    • numbers:格式化数字的功能方法类
    • strings:字符串对象的功能类,contains,startWiths,prepending/appending等等。
    • objects:对objects的功能类操作。
    • bools:对布尔值求值的功能方法。
    • arrays:对数组的功能类方法。
    • lists:对lists功能类方法
    • sets
    • maps

下面用一段代码来举例一些常用的方法:

  • dates
<h5>内置变量</h5>
<h6 th:text="${#dates.createNow()}">获取当前日期</h6>
  • strings
<h5>内置变量</h5>
<h6 th:text="${#dates.createNow()}">获取当前日期</h6>
<h6 th:text="${#strings.substring(text, 6, 9)}">截取字符串</h6>
<h6 th:text="${#strings.length(text)}">获得长度</h6>
<h6 th:text="${#strings.randomAlphanumeric(6)}">随机字符串</h6>
<h6 th:text="${#strings.equals(text, 'hello text....')}"></h6>
  • 使用thymeleaf布局

使用thymeleaf布局非常的方便

/resources/templates/目录下创建footer.html,内容如下

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<footer th:fragment="copy(title)">
&copy; murphymurphy<br>
<span th:text="${title}">title footer</span>
</footer>
</body>
</html>

在页面任何地方引入:

  • th:insert保留自己的主标签,保留th:fragment的主标签。
  • th:replace不要自己的主标签,保留th:fragment的主标签。
  • th:include保留自己的主标签,不要th:fragment的主标签。

返回的HTML如下:

<h5>thymeleaf布局</h5> 
<div>
		<footer>
		&copy; murphymurphy<br>
		<span>Yang</span> 
		</footer>
</div>
<footer>
		&copy; murphymurphy<br> 
		<span>Yang</span>
</footer>
<div>
		&copy; murphymurphy<br>
		<span>Yang</span> 
</div>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xmurphymurphy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值