ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Thymeleaf模板复习

2022-07-29 10:31:48  阅读:159  来源: 互联网

标签:... 复习 thymeleaf Thymeleaf 模板 th 表达式


Thymeleaf学习

三大模板

  1. jsp

  2. html thymeleaf

  3. tld freemarker

面试题: 什么是模板,为什么使用thymeleaf模板?

第一,Thymeleaf 在有网络和无网络的环境下皆可运行,即它可以让美工在浏览器查看页面的静态效果,也可以让程序员在服务器查看带数据的动态页面效果。

这是由于它支持 html 原型,然后在 html 标签里增加额外的属性来达到模板+数据的展示方式。浏览器解释 html 时会忽略未定义的标签属性,所以 thymeleaf 的模板可以静态地运行;当有数据返回到页面时,Thymeleaf 标签会动态地替换掉静态内容,使页面动态显示。

第二,Thymeleaf 开箱即用的特性。它提供标准和spring标准两种方言,可以直接套用模板实现JSTL、 OGNL表达式效果,避免每天套模板、该jstl、改标签的困扰。同时开发人员也可以扩展和创建自定义的方言。

第三,Thymeleaf 提供spring标准方言和一个与 SpringMVC 完美集成的可选模块,可以快速的实现表单绑定、属性编辑器、国际化等功能。

跟以前的技术做对比

image-20220728223633173

Th:xxx 覆盖原有属性

Th:text/th:utext 显示文本 行内 [[{})]

Th:each

${} 取值

~{} 代码段

@{} 相对于项目的绝对路径

 

第一章 模板引擎-简介和比较

1.1 Spring Boot提供了大量模板引擎技术

包含FreeMarker,Groovy,Thymeleaf,Velocity和Mustache,Spring Boot中推荐使用Thymeleaf作为模板引擎.因为Thymeleaf提供了完美的SpringMVC支持.

Thymeleaf是一个java类库,他是一个xml/xhtml/html5的模板引擎,可以作为mvc的web应用的view层。

1.2 Thymeleaf还提供了额外的模块与Spring MVC集成

所以我们可以使用Thymeleaf完全替代jsp。

spring Boot通过org.springframework.boot.autoconfigure.thymeleaf包对Thymeleaf进行了自动配置。

通过ThymeleafAutoConfiguration类对集成所需要的bean进行自动配置。

包括templateResolver,templateEngine,thymeleafViewResolver的配置。

img

1.3 模板引擎-简介和比较

img

1.4 模板引擎

JSP、Velocity、Freemarker、Thymeleaf

img

SpringBoot推荐的Thymeleaf;语法更简单,功能更强大;

 

第二章 Thymeleaf使用

2.1 Thymeleaf使用

org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration

ThymeleafViewResolver

org.springframework.boot.autoconfigure.thymeleaf.ThymeleafProperties

  @ConfigurationProperties(prefix = "spring.thymeleaf")
  public class ThymeleafProperties {
  private static final Charset DEFAULT_ENCODING = Charset.forName("UTF‐8");
  private static final MimeType DEFAULT_CONTENT_TYPE = MimeType.valueOf("text/html");
  public static final String DEFAULT_PREFIX = "classpath:/templates/";
  public static final String DEFAULT_SUFFIX = ".html";
  …
  }

只要我们把HTML页面放在classpath:/templates/thymeleaf就能自动渲染

导入thymeleaf的名称空间

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

使用thymeleaf语法

  <!DOCTYPE html>
  <html lang="en" xmlns:th="http://www.thymeleaf.org">
  <head>
  <meta charset="UTF‐8">
  <title>Title</title>
  </head>
  <body>
  <h1>成功!</h1>
  <!‐‐th:text 将div里面的文本内容设置为 ‐‐>
  <div th:text="${hello}">这是显示欢迎信息</div>
  </body>
  </html>

语法规则

th:text;改变当前元素里面的文本内容

th:任意html属性;来替换原生属性的值

  map.put("hello","<h1>你好</h1>");
  map.put("users",Arrays.asList("zhangsan","lisi","wangwu"));
 
  <!--th:text 将div里面的文本内容设置为 -->
  <div id="div01" class="myDiv" th:id="${hello}" th:class="${hello}" th:text="${hello}">这是显示欢迎信息</div>
  <hr/>
  <div th:text="${hello}"></div> <!--转译特殊字符,特殊符号原方不动输出-->
  <div th:utext="${hello}"></div> <!--会转译字符,特殊符号被转译后输出结果-->
  <hr/>
   
  <!-- th:each每次遍历都会生成当前这个标签: 3个h4 -->
  <h4 th:text="${user}" th:each="user:${users}"></h4>
  <hr/>
  <h4>
      <span th:each="user:${users}"> [[${user}]] </span> <!--inlning 行内写法 [[]]等价于th:text     [()]等价于th:utext-->
  </h4>

th:text ------> [[${...}]]

th:utext -------> [(${...})]

  <html xmlns:th="http://www.thymeleaf.org">
  <link th:href="@{/bootstrap/css/bootstrap.min.css}" rel="stylesheet" />
  <span th:text="${singlePerson.name}">姓名</span>
  <li class="list-group-item" th:each="person:${people}"></li>
  <script th:src="@{bootstrap/js/bootstrap.min.js}"></script>
  <script th:inline="javascript">
      var single=[[${singlePerson}]];
      console.log(single.name+"/"+single.age);
  </script>

 

第三章 Thymeleaf-语法

3.1 使用 th:text

3.1.1 外部文本(消息)(了解就好,ali开发几十年才走向国际)

 

Welcome Message

 

外部文本的概念: 外部文本抽取模板代码片段到模板文件外面, 使外部文本可以存在另一个文件中(比如 properties 文件). 通常把外部文本叫做消息(messages).

Thymeleaf 通过 #{...} 语法来使用消息.

在 springmvc 中使用消息要额外配置 ResourceBundleMessageSource 这个 bean:

   // 用于外部文本及国际化消息
      @Bean
      public ResourceBundleMessageSource messageSource() {
          ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
          messageSource.setBasename("messages");
          return messageSource;
    }

这个 bean 会去 classpath 根目录下去寻找 messages 为基名的 properties 文件.

比如,messages.properties, messages_en_US.properties, messages_zh_CN.properties.

th:text 外部文本会替换 p 标签内的内容.

3.1.2 使消息不转换 html 标签

如果我们在 messages.properites 中这么写: index.welcome=Welcome to SpringMVC

那么 thymeleaf 会转成 <p>Welcome to SpringMVC</p> 这显然不是我们想要的. 这时候就可以用 th:utext(for “unescaped text)

3.1.3 使用并显示变量

变量概念: 存在 java web 上下文中的变量. 比如 request, session, application, page ...

${...} 语法可以用来显示变量. 花括号内使用的是 ognl 表达式语言.

springmvc 中用 spel 语言代替 ognl 语言.

3.2 标准表达式语法

  • 变量表达式: ${...}

    • 选择变量表达式: *{...}

    • 消息表达式: #{...}

    • URL 表达式: @{...}

    • 代码段表达式: ~{...}

  • 字面量

    • 文本字面量: 'some text'

    • 数值字面量: 0, 34, 3.0, 12.3

    • 布尔值字面量: true, false

    • Null 值字面量: null

    • Tokens 字面量: one, content, sometext, ...

image-20220728225319415

3.3 消息

消息中也可以包含变量, 比如在 index.welcome 中, 想打印出时间:# 在 messages.properties 文件中用 {0}, {1}, {2}, ... 占位符

index.welcome=Welcome to SpringMVC, time is: {0}

那么在 index.html 模板文件中就可以这样写:<p th: utext="#{index.welcome(${date})}">Welcome message</p>

其中 ${date} 就像一个参数那样被传进去了.

3.4 变量

3.4.1变量表达式 ${...}

用的是 ognl(对象图导航语言). 在 springmvc 中用 spel(spring 表达式语言)代替. 其实两者在大部分情况下用法是相同的.

下面看几个例子就知道变量表达式的大部分用法了.

  <!-- springmvc 保存了一个 model 对象: departments -->
  <!-- 获取所有 departments -->
  <p th:text="${departments}"></p>
  <!-- 获取 departments 的第一个元素 -->
  <p th:text="${departments[0]}"></p>
  <!-- 获取第一个 department 对象的 name 属性 -->
  <p th:text="${departments[0].name}"></p>
  <!-- 也可以用 ['name'] 来获取第一个 department 对象的 name 属性 -->
  <p th:text="${departments[0]['name']}"></p>
  <!-- 甚至可以调用方法! -->
  <p th:text="${departments[0].getId()}"></p>
  <p th:text="${departments[0]['name'].substring(0, 1)}"></p>

3.4.2内置基本对象

加#号 取的是原生的servletAPI

不加# 取的是thymeleaf包装的API

下面是一些内置的基本对象, 可以用 # 符号直接使用

  ctx: the context object.
  vars: the context variables.
  locale: the context locale.
  request: (only in Web Contexts) the HttpServletRequest object.
  response: (only in Web Contexts) the HttpServletResponse object.
  session: (only in Web Contexts) the HttpSession object.
  servletContext: (only in Web Contexts) the ServletContext object.

使用例子:

country: <span th:text="${#***\*locale\****.country}"></span>

3. 4.3 内置工具对象

统统加#才能取到

除了基本对象, thymeleaf 还提供了一组工具对象.

execInfo: information about the template being processed.
messages: methods for obtaining externalized messages inside variables expressions, in the same way as they would be obtained using #{…} syntax.
uris: methods for escaping parts of URLs/URIs
conversions: methods for executing the configured conversion service (if any).
dates: methods for java.util.Date objects: formatting, component extraction, etc.
calendars: analogous to #dates, but for java.util.Calendar objects.
numbers: methods for formatting numeric objects.
strings: methods for String objects: contains, startsWith, prepending/appending, etc.
objects: methods for objects in general.
bools: methods for boolean evaluation.
arrays: methods for arrays.
lists: methods for lists.
sets: methods for sets.
maps: methods for maps.
aggregates: methods for creating aggregates on arrays or collections.
ids: methods for dealing with id attributes that might be repeated (for example, as a result of an iteration).

例子, 格式化时间:

<!-- 时间格式化 -->

time:<span th:text="${#dates.format(date, 'yyyy-MM-dd HH:mm:ss')}"></span><br>

4. 选择变量表达式

获取变量可以使用 ${...} 语法外, 还可以使用 {...}, 称为选择变量表达式***.

选择变量表达式与变量表达式的不同之处在于, 如果前面有一个选择对象了, 那么用它获取这个选择对象的属性或方法时, 可以不写对象名.

那么选择对象的概念是什么呢? 选择对象是用 th:object 表示的对象.

看例子:

<p>选择变量表达式</p>
<div th:object="${departments[1]}">
    <p th:text="*{id}"></p>
    <p th:text="*{name}"></p>
</div>
<p>等价的变量表达式</p>
<div>
    <p th:text="${departments[1].id}"></p>
    <!-- 如果没有 "选择对象", 那么 * 和 $ 是等价的 -->
    <p th:text="*{departments[1].name}"></p>
</div>

如果存在选择对象了, 那么在 ${...} 中也可以用 #object 来使用选择对象.

<p>${...} 中使用 #object 引用 "选择对象"</p>
<div th:object="document[2]">
    <!-- 以下三种方式在这种情况下是等价的 -->
    <p th:text="${#object.id}"></p>
    <p th:text="*{id}"></p>
    <p th:text="${document[2].id}"></p>
</div>

5. Link URL 表达式

链接 URL 表达式语法是 @{...}

有不同类型的 URLs:

绝对路径 URLs: http://localhost:8888/demo/index

相对路径 URLs:

页面相对: user/login.html

上下文相对: /employee/emps 注意用 / 打头, 会自动把上下文路径(比如 http://localhost:8888/demo) 路径加上去.

服务器相对(不重要)

协议相对(不重要)

例子:

<!-- Common styles and scripts -->
<link rel="stylesheet" type="text/css" media="all" th:href="@{/assets/css/base.css}">
<script type="text/javascript" th:src="@{/assets/ext/jquery-3.1.1-min.js}"></script>
<script type="text/javascript" th:src="@{/assets/js/codergege.js}"></script>
<!-- ... -->
<a href="#" th:href="@{/}">返回首页</a> <br>
<a href="#" th:href="@{/thymeleaf/demo1}">去 demo1 页面</a> <br>
<!-- 会生成 url: http://localhost:8888/demo/thymeleaf/demo1?username=tom -->
<a href="#" th:href="@{/thymeleaf/demo1(username=${employees[0].name})}">去 demo1 页面, 带参数</a> <br>
<!-- 会生成 url: http://localhost:8888/demo/thymeleaf/demo1/2 RESTful 风格的 url -->
<a href="#" th:href="@{/thymeleaf/demo1/{empId}(empId=${employees[1].id})}">去 demo1 页面, 带 RESTful 风格参数</a> <br>

中文会自动转码; 如果有多个参数,用逗号隔开.

image-20220729094237976

restful

image-20220729094452149

6代码段(fragment)

语法: ~{...}

最常见的用法是与 th:insert 或 th:replace 配合使用. 例如:

<!-- ~{...} 可以省略不写 -->
<header id="header" th:replace="fragment :: header"></header>
<footer id="footer" th:replace="~{fragment :: footer}"></footer>

image-20220729100447920

image-20220729100542268

这就是三者区别

<!--替换掉外层的div元素-->
<div th:replace="~{common::foot}"></div>
<!--在外层div中直接插入代码段-->
<div th:insert="~{common::foot}"></div>
<!--只包含代码段的文本-->
<div th:include="~{common::foot}"></div>

7.字面量

image-20220729101009584

image-20220729101025132

image-20220729101041299

8. 连接字符串

文本, 不管是文本字面量还是通过 ognl/spel 计算出来的文本, 都能用 + 操作符连接.

<span th:text="'Some literal text and ' + ${departments[0].name}"></span>

image-20220729101340932

9. 条件表达式与默认表达式

条件表达式由 3 个部分组成,

condition, then, else. 每个部分自身又是一个表达式, 即它们分别可以用变量(${...}, *{...}), 消息(#{...}), URLs(@{...}), 字面量等来表示.

 <!-- else 部分可以省略, 这种情况下, 如果条件为 false, null 值会被返回 -->
 <p th:class="${employees[0].id % 2 == 0}? 'even'" th:text="${employees[0].name}"></p>
 <p th:class="${employees[1].id % 2 == 0}? 'even': 'odd'" th:text="${employees[1].name}"></p>
 <p th:class="${employees[2].id % 2 == 0}? 'even': 'odd'" th:text="${employees[2].name}"></p>
 <!-- ?: 默认表达式 -->
 <span th:text="${employees[0].getGender()}?: '没有指定性别'"></span> <br>
 <span th:text="${employees[2].getEmail()}?: '没有指定邮箱'"></span> <br>
 <!-- 可以嵌套混合, 嵌套的话用 () 包起来 -->
 <span th:text="(${employees[0].getGender()} == 1 ? '男': '女')?: '没有指定性别'"></span>

10. No-Op 操作符(_)

 No-Op 操作符指明期待的表达式结果不做任何事情. 比如说 th:text 中最后计算结果是 _,那么 th:text 元素根本就不会生成.
 <p th:text="_">这里的内容不会被 th:text 替换</p>
 <p th:text="${employees[0].email}?: _">没有指定电子邮箱</p>

11.数据转换与格式化

Thymeleaf 的变量表达式(${...}, *{...})使用 {{...}} 来表示需要进行转换. 允许我们使用自定义的数据转换服务来转换表达式返回结果.

使用 thymeleaf-spring3 和 thymeleaf-spring4 的话, 会自动调用 spring 的 ConversionService.

12.预处理表达式

用双下划线 ... 包裹普通的表达式就可以.

3.5设置属性值

本章学习 thymeleaf 如何设置或修改 html 元素属性.

3.5.1 设置任意属性 th:attr

可以用 th:attr 来设置任意属性.

 <!-- 替换 action 属性 -->
 <form action="#" th:attr="action=@{/suscribe}" >
     <input type="text" name="name">
     <input type="text" name="gender">
     <input type="text" name="birthday">
     <input type="text" name="email">
     <!-- todo select departments -->
     <!-- 一次替换多个属性值 1) submit 按钮的 value 属性; 2) class 属性 -->
     <input type="submit" value="Submit" th:attr="value=#{form.submit}, class='sep'">
 </form>

3.5.2 设置指定属性

一般 th:attr 很少会用到, 而是会直接使用指定的 th:*.

比如已经用过的 th:href, th:text, th:value, th:action ...

几乎所有的 html 元素属性都有对应的 th:* 版本.

image-20220729102257809

3.6 迭代

3.6.1 迭代初步

使用 th:each

 <ul>
     <li>
         <span class="list">编号</span>
         <span class="list">姓名</span>
         <span class="list">性别</span>
         <span class="list">生日</span>
         <span class="list">部门</span>
         <span class="list">编辑</span>
         <span class="list">删除</span>
     </li>
     <li th:each="emp : ${employees}">
         <span class="list" th:text="${emp.id}"></span>
         <span class="list" th:text="${emp.name}"></span>
         <span class="list" th:text="${emp.gender == 1} ? '男': '女'"></span>
         <span class="list" th:text="${{emp.birthday}}"></span>
         <span class="list" th:text="${emp.department.name}"></span>
         <span class="list"><a href="#">编辑</a></span>
         <span class="list"><a href="#">删除</a></span>
     </li>
 </ul>

th:each 用起来很方便, 就像 java 中的 for 循环一样.

 for(Employee emp: employees) {
 ​
   // Do something
 ​
 }

在 thymeleaf 中使用迭代太方便了! 回想 jstl 那些坑爹的标签, 泪都留下来...

可以用 th:each 迭代的 java 类型

th:each 不仅仅可以对 java.util.List 类型迭代, 实际上大部分的 java 集合类型都可以使用它来迭代.

实现了 java.util.Iterable 接口的对象

实现了 java.util.Enumeration 接口的对象

实现了 java.util.Iterator 接口的对象, 不会一次性读入内存, 返回一个读一个.

实现了 java.util.Map 接口的对象, 这时候迭代的值是 java.util.Map.Entry.

任何数组

3.6.2 保存迭代状态

th:each 还提供了一个变量可以保存迭代状态. 用法是 th:each="emp, status: ${employees}"

状态变量保存了以下数据:

*index* 属性, 0 开始的索引值

*count* 属性, 1 开始的索引值

*size* 属性, 集合内元素的总量

*current* 属性, 当前的迭代对象

*even/odd* 属性, boolean 类型的, 用来判断是否是偶数个还是奇数个

*first* 属性, boolean 类型, 是否是第一个

*last* 属性, boolean 类型, 是否是最后一个

看例子:

 <ul>
     <li>
         <span class="list">编号</span>
         <span class="list">姓名</span>
         <span class="list">性别</span>
         <span class="list">生日</span>
         <span class="list">部门</span>
         <span class="list">编辑</span>
         <span class="list">删除</span>
         <span class="list status">当前迭代状态</span>
     </li>
     <li th:each="emp, status: ${employees}" th:class="${status.odd} ? 'odd': 'even'">
         <span class="list" th:text="${emp.id}"></span>
         <span class="list" th:text="${emp.name}"></span>
         <span class="list" th:text="${emp.gender == 1} ? '男': '女'"></span>
         <span class="list" th:text="${{emp.birthday}}"></span>
         <span class="list" th:text="${emp.department.name}"></span>
         <span class="list"><a href="#">编辑</a></span>
         <span class="list"><a href="#">删除</a></span>
         <span class="list status" th:text="|index: ${status.index}; count: ${status.count}; size: ${status.size}; first: ${status.first}|"></span>
     </li>
 </ul>

image-20220729102750675

也可以不显式声明 status 变量, thymeleaf 会自动创建一个, 状态变量的名称是你声明的

变量加上 Stat, 比如上面的例子 emp: ${emplopyees} 会创建一个 empStat 的状态变量

标签:...,复习,thymeleaf,Thymeleaf,模板,th,表达式
来源: https://www.cnblogs.com/wangshikang/p/16531421.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有