跳过正文
  1. 文章/
  2. Java/
  3. SpringFramework/
  4. SpringBoot/

2、Thymeleaf

·3672 字·8 分钟· loading · loading · ·
Java SpringFramework SpringBoot
GradyYoung
作者
GradyYoung
SpringBoot - 点击查看当前系列文章
§ 2、Thymeleaf 「 当前文章 」

JSP的缺陷
#

  • JSP就是一个Servlet ,生命周期:翻译,编译,加载,初始化,服务,销毁
  • Servlet一定要放置在Servlet容器中才可以运行,浏览器不能直接解析
  • JSP页面一般构成:HTML + CSS + JS + Java代码 + JSTL标记
  • 由此的坏处:
    • JSP必须要在Servlet容器解析成HTML,才可以返回到浏览器中(系统:不管是静态请求也好, 还是动态请求,都压到Tomcat服务器,这就可能导致Tomcat解决动态请求的能力有所降低)
    • JSP必须要在Servlet容器解析成HTML,这就意味着百度,谷歌,以及其他的搜索引擎无法去收录
  • JSP从2015年之前,就开始走向灭亡,取而代之的是,HTML + 模板引擎

模板引擎
#

  • 使用符号或者自定义标记 + 网页中不变的东西 = 模板引擎
  • 模板引擎的作用: 将页面中动态的内容,使用标记或某些符号,进行静态的替换。从而做到:浏览器认为整个网页都是静态的内容(进而可以做到:浏览器缓存HTML,Nginx等服务器缓存HTML) 从而提升系统的整合响应性能
  • 常见的模板引擎**:Freemarker,thymeleaf,velocity**

Thymeleaf的特点
#

Thymeleaf 模板引擎具有以下特点:

  • 动静结合:Thymeleaf 既可以直接使用浏览器打开,查看页面的静态效果,也可以通过 Web 应用程序进行访问,查看动态页面效果。
  • 开箱即用:Thymeleaf 提供了 Spring 标准方言以及一个与 SpringMVC 完美集成的可选模块,可以快速的实现表单绑定、属性编辑器、国际化等功能。
  • 多方言支持:它提供了 Thymeleaf 标准和 Spring 标准两种方言,可以直接套用模板实现 JSTL、 OGNL 表达式;必要时,开发人员也可以扩展和创建自定义的方言。
  • 与 SpringBoot 完美整合:SpringBoot 为 Thymeleaf 提供了的默认配置,并且还为 Thymeleaf 设置了视图解析器,因此 Thymeleaf 可以与 Spring Boot 完美整合。

Thymeleaf的基本使用
#

Thymeleaf通常适用于前后端不分离的页面

1、创建SpringBoot应用

2、导入依赖

<!-- 导入thymeleaf的启动器依赖:完成对thymeleaf的全部支持,自动配置了对应视图解析器 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

3、配置文件

# 指定模板所在的目录
spring.thymeleaf.prefix=classpath:/templates/
# 检查模板路径是否存在
spring.thymeleaf.check-template-location=true
# 后缀
spring.thymeleaf.suffix=.html
# 默认HTML
spring.thymeleaf.mode=HTML
# 是否缓存,开发环境true、生产环境false
spring.thymeleaf.cache=false
# 解析字符集编码
spring.thymeleaf.encoding=UTF-8
spring:
  thymeleaf:
    encoding: UTF-8
    prefix: classpath:/templates/
    mode: HTML
    suffix: .html

4、html页面放在src/main/resources/templates

html模板文件需要引入命名空间http://www.thymeleaf.org

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h1 th:text=""></h1>
    </body>
</html>

5、js、css等静态资源放在src/main/resources/static

由于SpringBoot约定大于配置的特性,默认的静态文件目录为src/main/resources/static,也可以通过配置文件进行更换

注意:引入静态资源的时候不需要加static这一层路径

spring:
  resources:
    static-locations: classpath:/myStatic/

Thymeleaf语法规则
#

标准表达式
#

Thymeleaf 模板引擎支持多种表达式:

  • 变量表达式:${...}
  • 选择变量表达式:*{...}
  • 链接表达式:@{...}
  • 国际化表达式:#{...}
  • 片段引用表达式:~{...}

变量表达式
#

使用${}包裹的表达式被称为变量表达式,该表达式具有以下功能:

  • 获取对象的属性和方法
    • ${person.name}
  • 使用内置的基本对象
    • #ctx:上下文对象
    • #vars:上下文变量
    • #locale:上下文的语言环境
    • #request:HttpServletRequest 对象(仅在 Web 应用中可用)
    • #response:HttpServletResponse 对象(仅在 Web 应用中可用)
    • #session:HttpSession 对象(仅在 Web 应用中可用)
      • ${#session.getAttribute('map')}
      • ${session.map}
    • #servletContext:ServletContext 对象(仅在 Web 应用中可用)
  • 使用内置的工具对象
    • strings:字符串工具对象,常用方法有:equals、equalsIgnoreCase、length、trim、toUpperCase、toLowerCase、indexOf、substring、replace、startsWith、endsWith,contains 和 containsIgnoreCase 等
      • ${#strings.equals('ygang',name)}
    • 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:text="${#dates.format(date, 'yyyy-MM-dd HH:mm:ss')}"

选择变量表达式
#

选择变量表达式与变量表达式功能基本一致,只是在变量表达式的基础上增加了与 th:object 的配合使用。当使用 th:object 存储一个对象后,我们可以在其后代标签中使用选择变量表达式*{...}获取该对象中的属性,其中,*即代表该对象。

<div th:object="${user}" >
    <p th:text="*{name}">name</p>
</div>
<!-- 等价于 -->
<div>
    <p th:text="${user.name}">name</p>
</div>

链接表达式
#

不管是静态资源的引用,还是 form 表单的请求,凡是链接都可以用链接表达式 @{...}

链接表达式的形式结构如下:

  • 无参请求:@{/xxx}
  • 有参请求:@{/xxx(k1=v1,k2=v2)}
<link th:href="@{/asserts/css/signin.css}" rel="stylesheet">

国际化表达式
#

消息表达式一般用于国际化的场景。

th:text="#{msg}"

片段引用表达式
#

片段引用表达式用于在模板页面中引用其他的模板片段,该表达式支持以下 2 中语法结构:

  • 推荐:~{templatename::fragmentname}

  • 支持:~{templatename::#id}

    • templatename:模版名,Thymeleaf 会根据模版名解析完整路径:/resources/templates/templatename.html,要注意文件的路径。

    • fragmentname:片段名,Thymeleaf 通过 th:fragment 声明定义代码块,即:th:fragment="fragmentname"

    • id:HTML 的 id 选择器,使用时要在前面加上 # 号,不支持 class 选择器。

    • 通常情况下,~{} 可以省略

th属性
#

th:id
#

替换 HTML 的 id 属性

th:text
#

文本替换,转义特殊字符,也就是会显示html标签为文本

th:utext
#

文本替换,不转义特殊字符,也就是会将html标签解析

th:object
#

在父标签选择对象,子标签使用 *{…} 选择表达式选取属性值。 没有选择对象,那子标签使用选择表达式和 ${…} 变量表达式是一样的效果。 同时即使选择了对象,子标签仍然可以使用变量表达式。

th:value
#

替换 value 属性

th:with
#

局部变量赋值运算

<div th:with="isEvens = ${prodStat.count}%2 == 0"  th:text="${isEvens}"></div>

th:style
#

设置样式

th:onclick
#

设置点击事件

th:each
#

遍历,支持 Iterable、Map、数组等。

<table>
    <tr th:each="m:${session.map}">
        <td th:text="${m.getKey()}"></td>
        <td th:text="${m.getValue()}"></td>
    </tr>
</table>

对于遍历,也可以拿到遍历中的状态变量,如索引

<table>
    <tr th:each="m,status:${session.map}">
        <td th:text="${m.getKey()}"></td>
        <td th:text="${m.getValue()}"></td>
    </tr>
</table>
  • status有如下属性
    • index:当前迭代对象的迭代索引,从0开始,这是索引属性;
    • count:当前迭代对象的迭代索引,从1开始,这个是统计属性;
    • size:迭代变量元素的总量,这是被迭代对象的大小属性;
    • current:当前迭代变量;
    • even/odd:布尔值,当前循环是否是偶数/奇数(从0开始计算);
    • first:布尔值,当前循环是否是第一个;
    • last:布尔值,当前循环是否是最后一个;

th:if
#

根据条件判断是否需要展示此标签

th:unless
#

th:if判断相反,满足条件时不显示

th:switch
#

与 Java 的 switch case语句类似,通常与 th:case 配合使用,根据不同的条件展示不同的内容

<div th:switch="${name}">
    <span th:case="a">ygang</span>
    <span th:case="b">top</span>
</div>

th:fragment
#

模板布局,类似 JSP 的 tag,用来定义一段被引用或包含的模板片段

th:insert
#

将使用 th:fragment 属性指定的模板片段(包含标签)插入到当前标签中。

th:replace
#

将使用 th:fragment 属性指定的模板片段(包含标签)替换当前整个标签。

th:include
#

将使用 th:fragment 属性指定的模板包含的内容(不包含标签)插入到当前标签中。

th:selected
#

设置select 选择框选中

<select>
    <option>---</option>
    <option th:selected="${name=='a'}">
        ygang
    </option>
    <option th:selected="${name=='b'}">
        top
    </option>
</select>

th:src
#

替换 HTML 中的 src 属性

th:inline
#

内联属性; 该属性有 text、none、javascript 三种取值, 在 <script> 标签中使用时,js 代码中可以获取到后台传递页面的对象

<script type="text/javascript" th:inline="javascript">
    var name = [[${name}]];
    alert(name)
</script>

th:action
#

替换表单提交地址

内联表达式
#

[[…]]
#

相当于th:text

<p>The message is : [[${htmlContent}]]</p>

[(…)]
#

相当于th:utext

<p>The message is : [(${htmlContent})]</p>

th:inline
#

描述
none 禁止内联表达式,可以原样输出 [[]] 和 [()] 字符串
text 文本内联,可以使用 th:each 等高级语法
css 样式内联,如:<style th:inline="css">
javascript 脚本内联,如:<style th:inline="javascript">

组件化开发
#

定义模板,在templates/commons.html

<div th:fragment="fragment-name" id="fragment-id">
    <span>公共页面片段</span>
</div>

引入模板

<!--片段名引入-->
<div th:insert="commons::fragment-name"></div>
<!--id选择器引入-->
<div th:insert="commons::#fragment-id"></div>

传参
#

定义模板,在templates/commons.html

<div th:fragment="fragment-name(name,age)" id="fragment-id">
    <span>公共页面片段</span>
</div>

引入模板

<!--片段名引入并传参-->
<div th:insert="commons::fragment-name(${name},18)"></div>
<!--片段名替换并传参-->
<div th:replace="commons::fragment-name(${name},18)"></div>
SpringBoot - 点击查看当前系列文章
§ 2、Thymeleaf 「 当前文章 」