SpringBoot与Thymeleaf入门级操作

使用Thymeleaf 三大理由:

  1. 简洁漂亮 容易理解
  2. 完美支持HTML5 使用浏览器直接打开页面
  3. 不新增标签 只需增强属性

学习目标

  • 快速掌握Thymeleaf的基本使用:五大基础语法,常用内置对象

快速查阅

源码下载:springboot-web-thymeleaf-enhance

— Hey Man,Don’t forget to Star or Fork . —

官方指南:Thymleaf 3.0 官方教程

使用教程

温馨提示:Thymeleaf 最为显著的特征是增强属性,任何属性都可以通过th:xx 来完成交互,例如th:value最终会覆盖value属性。

一、基础语法

变量表达式 ${}

使用方法:直接使用 th:xx = "${}" 获取对象属性 。例如:

<form id="userForm">
    <input id="id" name="id" th:value="${user.id}">
    <input id="username" name="username" th:value="${user.username}">
    <input id="password" name="password" th:value="${user.password}">
</form>

选择变量表达式 *{}

使用方法:首先通过 th:object 获取对象,然后使用 th:xx = "*{}"获取对象属性。

这种简写风格极为清爽,推荐大家在实际项目中使用。 例如:

<form id="userForm" th:object="${user}">
    <input id="id" name="id" th:value="*{id}">
    <input id="username" name="username" th:value="*{username}">
    <input id="password" name="password" th:value="*{password}">
</form>

链接表达式 @{}

使用方法:通过链接表达式 @{}直接拿到应用路径,然后拼接静态资源路径。例如:

<script th:src="@{/webjars/jquery/jquery.js}"></script>
<link th:href="@{/webjars/bootstrap/css/bootstrap.css}" rel="stylesheet" type="text/css">

片段表达式 ~{}

片段表达式是Thymeleaf的特色之一,细粒度可以达到标签级别,这是JSP无法做到的。

片段表达式拥有三种语法:

  • ~{ viewName } &#x8868;&#x793A;&#x5F15;&#x5165;&#x5B8C;&#x6574;&#x9875;&#x9762;
  • ~{ viewName ::selector} &#x8868;&#x793A;&#x5728;&#x6307;&#x5B9A;&#x9875;&#x9762;&#x5BFB;&#x627E;&#x7247;&#x6BB5; &#x5176;&#x4E2D;selector&#x53EF;&#x4E3A;&#x7247;&#x6BB5;&#x540D;&#x3001;jquery&#x9009;&#x62E9;&#x5668;&#x7B49;
  • ~{ ::selector} &#x8868;&#x793A;&#x5728;&#x5F53;&#x524D;&#x9875;&#x5BFB;&#x627E;

使用方法:首先通过 th:fragment定制片段 ,然后通过 th:replace 填写片段路径和片段名。例如:

<!-- /views/common/head.html-->
<head th:fragment="static">
        <script th:src="@{/webjars/jquery/3.3.1/jquery.js}"></script>
</head>
<!-- /views/your.html -->

在实际使用中,我们往往使用更简洁的表达,去掉表达式外壳直接填写片段名。例如:

<!-- your.html -->

值得注意的是,使用替换路径 th:replace 开头请勿添加斜杠,避免部署运行的时候出现路径报错。(因为默认拼接的路径为 spring.thymeleaf.prefix = classpath:/templates/

消息表达式

即通常的国际化属性: #{msg} 用于获取国际化语言翻译值。例如:

<title th:text="#{user.title}"></title>

其它表达式

在基础语法中,默认支持字符串连接、数学运算、布尔逻辑和三目运算等。例如:

<input name="name" th:value="${'I am '+(user.name!=null?user.name:'NoBody')}">

二、内置对象

官方文档:附录A: Thymeleaf 3.0 基础对象

官方文档:附录B: Thymeleaf 3.0 工具类

七大基础对象:

  • ${#ctx} 上下文对象,可用于获取其它内置对象。
  • ${#vars}: 上下文变量。
  • ${#locale}:上下文区域设置。
  • ${#request}: HttpServletRequest对象。
  • ${#response}: HttpServletResponse对象。
  • ${#session}: HttpSession对象。
  • ${#servletContext}: ServletContext对象。

常用的工具类:

  • #strings:字符串工具类
  • #lists:List 工具类
  • #arrays:数组工具类
  • #sets:Set 工具类
  • #maps:常用Map方法。
  • #objects:一般对象类,通常用来判断非空
  • #bools:常用的布尔方法。
  • #execInfo:获取页面模板的处理信息。
  • #messages:在变量表达式中获取外部消息的方法,与使用#{…}语法获取的方法相同。
  • #uris:转义部分URL / URI的方法。
  • #conversions:用于执行已配置的转换服务的方法。
  • #dates:时间操作和时间格式化等。
  • #calendars:用于更复杂时间的格式化。
  • #numbers:格式化数字对象的方法。
  • #aggregates:在数组或集合上创建聚合的方法。
  • #ids:处理可能重复的id属性的方法。

三、迭代循环

想要遍历 List集合很简单,配合 th:each 即可快速完成迭代。例如遍历用户列表:

<div th:each="user:${userList}">
    &#x8D26;&#x53F7;&#xFF1A;<input th:value="${user.username}">
    &#x5BC6;&#x7801;&#xFF1A;<input th:value="${user.password}">
</div>

在集合的迭代过程还可以获取状态变量,只需在变量后面指定状态变量名即可,状态变量可用于获取集合的下标/序号、总数、是否为单数/偶数行、是否为第一个/最后一个。例如:

<div th:each="user,stat:${userList}" th:class="${stat.even}?'even':'odd'">
    &#x4E0B;&#x6807;&#xFF1A;<input th:value="${stat.index}">
    &#x5E8F;&#x53F7;&#xFF1A;<input th:value="${stat.count}">
    &#x8D26;&#x53F7;&#xFF1A;<input th:value="${user.username}">
    &#x5BC6;&#x7801;&#xFF1A;<input th:value="${user.password}">
</div>

如果缺省状态变量名,则迭代器会默认帮我们生成以变量名开头的状态变量 xxStat, 例如:

<div th:each="user:${userList}" th:class="${userStat.even}?'even':'odd'">
    &#x4E0B;&#x6807;&#xFF1A;<input th:value="${userStat.index}">
    &#x5E8F;&#x53F7;&#xFF1A;<input th:value="${userStat.count}">
    &#x8D26;&#x53F7;&#xFF1A;<input th:value="${user.username}">
    &#x5BC6;&#x7801;&#xFF1A;<input th:value="${user.password}">
</div>

四、条件判断
条件判断通常用于动态页面的初始化,例如:

<div th:if="${userList}">
    <div>&#x7684;&#x786E;&#x5B58;&#x5728;..</div>
</div>

如果想取反则使用unless 例如:

<div th:unless="${userList}">
    <div>&#x4E0D;&#x5B58;&#x5728;..</div>
</div>

五、日期格式化

使用默认的日期格式(toString方法) 并不是我们预期的格式: Mon Dec 03 23:16:50 CST 2018

<input type="text" th:value="${user.createTime}">

此时可以通过时间工具类 #dates来对日期进行格式化: 2018-12-03 23:16:50

<input type="text" th:value="${#dates.format(user.createTime,'yyyy-MM-dd HH:mm:ss')}">

六、内联写法

  • (1)为什么要使用内联写法?·答:因为 JS无法获取服务端返回的变量。
  • (2)如何使用内联表达式?答:标准格式为: [[${xx}]] ,可以读取服务端变量,也可以调用内置对象的方法。例如获取用户变量和应用路径:
<script th:inline="javascript">
  var user = [[${user}]];`
  var APP_PATH = [[${#request.getContextPath()}]];
  var LANG_COUNTRY = [[${#locale.getLanguage()+'_'+#locale.getCountry()}]];
</script>
  • (3)标签引入的JS里面能使用内联表达式吗?答:不能!内联表达式仅在页面生效,因为 Thymeleaf只负责解析一级视图,不能识别外部标签JS里面的表达式。

七、国际化

需要了解更多关于国际化的精彩描述请前往 SpringBoot 快速实现国际化i18n

例如在国际化文件中编写了user.title这个键值,然后使用 #{}读取这个KEY即可获取翻译。

<title th:text="#{user.title}">&#x7528;&#x6237;&#x767B;&#x9646;</title>

八、详细教程

======== 有了上述基础后 下面正式开始Thymeleaf 的详细教程 ==============

首先通过Spring Initializr创建项目,

然后在POM文件引入 web &#x3001;thymeleaf等依赖

<dependencies>
        <dependency><!--Web相关依赖-->
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-web</artifactid>
        </dependency>
        <dependency><!--页面模板依赖-->
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-thymeleaf</artifactid>
        </dependency>
        <dependency><!--热部署依赖-->
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-devtools</artifactid>
            <scope>runtime</scope>
        </dependency>
    </dependencies>

然后在 src/main/resources/application.yml 配置页面路径:

spring:
  thymeleaf:
    cache: false #&#x5173;&#x95ED;&#x7F13;&#x5B58;
    prefix: classpath:/views/ #&#x8C03;&#x6574;&#x9875;&#x9762;&#x8DEF;&#x5F84;

接着在 src/main/java/com/hehe/web/UserController 获取用户信息:

@RestController
public class UserController {
    private List<user> userList = new ArrayList<>();
    {
        userList.add(new User("1", "socks", "123456", new Date()));
        userList.add(new User("2", "admin", "111111", new Date()));
        userList.add(new User("3", "jacks", "222222", null));
    }
    @GetMapping("/")
    public ModelAndView index() {
        return new ModelAndView("user/user", "userList", userList);
    }
}
public class User {
    private String id;
    private String username;
    private String password;
    private Date createTime;
    //&#x8BF7;&#x8BFB;&#x8005;&#x81EA;&#x884C;&#x8865;&#x5145; &#x6784;&#x9020;&#x5668;&#x548C; get/set&#x65B9;&#x6CD5;..

}
</user>

开始编写公共页面: src/main/resources/views/common/head.html ,其中 static为页面片段:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<!--声明static为页面片段名称-->
<head th:fragment="static">
    <link th:href="@{/webjars/bootstrap/css/bootstrap.css}" rel="stylesheet" type="text/css">
    <script th:src="@{/webjars/jquery/jquery.js}"></script>
</head>
</html>

接着编写用户列表页: src/main/resources/views/user/user.html 配合 th:each显示用户列表信息。

使用说明:这里 th:replace="common/head::static" 表示将引用 ${spring.thymeleaf.prefix}/common/head.htmlstatic页面片段,值得注意的是由于替换路径默认会拼接前缀路径,所以开头切勿在添加斜杠,否则在打包成JAR部署运行时将提示报 Templates not found...

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title th:text="&#x7528;&#x6237;&#x4FE1;&#x606F;">User</title>
    <!--默认拼接前缀路径,开头请勿再添加斜杠,防止部署运行报错!-->
    <script th:replace="common/head::static"></script>
</head>
<body>
<div th:each="user,userStat:${userList}" th:class="${userStat.even}?'even':'odd'">
    &#x5E8F;&#x53F7;&#xFF1A;<input type="text" th:value="${userStat.count}">
    &#x8D26;&#x53F7;&#xFF1A;<input type="text" th:value="${user.username}">
    &#x5BC6;&#x7801;&#xFF1A;<input type="password" th:value="${user.password}">
    &#x65F6;&#x95F4;&#xFF1A;<input type="text" th:value="${user.createTime}">
    &#x65F6;&#x95F4;&#xFF1A;<input type="text" th:value="${#dates.format(user.createTime,'yyyy-MM-dd HH:mm:ss')}">
</div>
<script th:inline="javascript">
    //通过内联表达式获取用户信息
    var userList = [[${userList}]];
    console.log(userList)
</script>
</body>
</html>

然后编写单个用户页面:

至此大功告成,然后快速启动项目,如图所示:

SpringBoot与Thymeleaf入门级操作

快速启动项目

然后访问用户列表: http://localhost:8080,如图所示

SpringBoot与Thymeleaf入门级操作

然后访问单个用户: http://localhost:8080/user/1,如图所示:

SpringBoot与Thymeleaf入门级操作

Original: https://www.cnblogs.com/mysweetAngleBaby/p/16676670.html
Author: 一眼万年的星空
Title: SpringBoot与Thymeleaf入门级操作

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/621596/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 20220808-单例设计模式

    1. 设计模式 2 单例设计模式 2.1 懒汉式 2.2 饿汉式 2.3 区别 1. 设计模式 设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。 使用…

    Java 2023年6月15日
    086
  • 解决Tomcat部署工件中无子模块的工件

    本文是在尝试了刷新Maven项目、clean了Maven缓存并且重启IDEA之后任然无法在Tomcat中找到子模块对应的工件,这时就要试着模仿着自己创建一个模块父类的pom.xml…

    Java 2023年6月14日
    076
  • Spring Boot 使用 Log4j2

    Java 中比较常用的日志工具类,有 Log4j、SLF4j、Commons-logging(简称jcl)、Logback、Log4j2(Log4j 升级版)、Jdk Loggin…

    Java 2023年5月30日
    088
  • Java实现两种队列(数组和链表)

    @date 2022-09-13 17:50*/public class QueueLinked{ private static class Node{E item;Node ne…

    Java 2023年6月15日
    075
  • 4.如何避免缓存穿透、缓存击穿、缓存雪崩

    先来看一下缓存穿透,是指业务请求穿过了缓存层,落到持久化存储上。在大多数场景下,我们应用缓存是为了承载前端业务请求,缓存被击穿以后,如果请求量比较大,则会导致数据库出现风险。 以双…

    Java 2023年6月9日
    054
  • 枚举

    枚举 自定义类实现枚举 1.不需要提供set方法,因为枚举对象值通常为只读2.对枚举对象/属性使用final + static共同修饰,实现底层优化3.枚举对象名通常使用全部大写,…

    Java 2023年6月5日
    087
  • SpringCloud : Feign 使用 FastJson 解析数据

    Fastjson 版本1.2.60 Spring 版本 5.1.5.RELEASE SpringBoot 版本 2.1.5.RELEASE SpringCloud 版本 2.1.1…

    Java 2023年5月30日
    074
  • MySQL、Oracle元数据抽取分析

    最近接到个任务是抽取mysql和Oracle的元数据,大致就是在库里把库、schema、表、字段、分区、索引、主键等信息抽取出来,然后导成excel。 因为刚开始接触元数据,对这个…

    Java 2023年6月5日
    086
  • python圆周率计算(带进度条)

    3.波尔文四次迭代式 这个公式由乔纳森·波尔文和彼得·波尔文于1985年发表的。 bailey-borwein-plouffe算法 这个公式简称BBP公式,由David Baile…

    Java 2023年6月6日
    0110
  • 设计模式 23 访问者模式

    访问者模式(Visitor Pattern)属于 行为型模式 生活中经常会有这样的情况,同样的事物不同人有完全不同的感受,正所谓 一千个读者一千个哈姆雷特。 程序中也是一样,往往不…

    Java 2023年6月6日
    0106
  • Linux 搞乱、有趣的命令

    1、sl命令 你会看到一辆火车从屏幕右边开往左边…… 安装 sudo yum -y install sl 运行 sl 命令有 -a l F e几个选项,加上…

    Java 2023年6月5日
    077
  • MySQL定时任务(Event Scheduler)

    基于 MySQL 5.7,官方文档地址: 前置条件 — 查看开启状态 SHOW GLOBAL VARIABLES like ‘%event_scheduler%’; — 开启 …

    Java 2023年6月5日
    096
  • [springmvc]ssm框架整合超简单

    此整合没有具体的业务,因为ssm整合最难的点就在于配置文件的整合,因此这里只详细记录配置文件的整合 spring和dao整合将mybatis的配置文件的数据库连接和sqlsessi…

    Java 2023年6月6日
    0101
  • Objective-C 编程语言官网文档(十二)-线程

    Objective-C 提供了对线程同步以及异常绑定( “Exception Handling.” )的支持。要打开对这些特性的支持。可以使用GCC3.3以…

    Java 2023年5月30日
    065
  • Jenkins+gitlab+docker+harbor容器化自动部署详细流程

    环境:Linux版本:Centos7 一、更新源:yum update 二、安装docker:yum install docker -y 启动docker: systemctl s…

    Java 2023年6月13日
    078
  • 在java中跳出当前的多重嵌套循环

    在java中要跳出当前的多重嵌套循环可以有三种方式。 1.定义一个标记变量,在每一层循环中检查这个变量,如果检查结果匹配,则逐层跳出每层循环。 这种方式需要在每一层循环中检查标记变…

    Java 2023年5月29日
    068
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球