基于springboot对thymeleaf的使用

1
基于springboot对thymeleaf的使用

Thymeleaf

Thymeleaf是一个XML/XHTML/HTML5模板引擎,可用于Web与非Web环境中的应用开发。它是一个开源的Java库,基于Apache License 2.0许可,由Daniel Fernández创建,该作者还是Java加密库Jasypt的作者。

Thymeleaf提供了一个用于整合Spring MVC的可选模块,在应用开发中,你可以使用Thymeleaf来完全代替JSP或其他模板引擎,如Velocity、FreeMarker等。Thymeleaf的主要目标在于提供一种可被浏览器正确显示的、格式良好的模板创建方式,因此也可以用作静态建模。你可以使用它创建经过验证的XML与HTML模板。相对于编写逻辑或代码,开发者只需将标签属性添加到模板中即可。接下来,这些标签属性就会在DOM(文档对象模型)上执行预先制定好的逻辑。

官方文档: https://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf.html#what-is-thymeleaf

默认的模板配置路径为:src/main/resources/templates。当然也可以修改这个路径,可以看application.properties中的配置. springboot不用下面参数, 使用默认参数即可.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# thymeleaf start
# 开发时关闭缓存, 不然没办法看到实时页面
spring.thymeleaf.cache=false

# 是否检查模板位置, 默认为true
spring.thymeleaf.check-template-location=true
# 模板的content-type值, 默认为text/html
spring.thymeleaf.servlet.content-type=text/html
# 是否开启视图解析, 默认为true
spring.thymeleaf.enabled=true
# 模板的编码, 默认为utf-8
spring.thymeleaf.encoding=utf-8
# 要排除的模板名称
#spring.thymeleaf.excluded-view-names=
# 模板模式, 默认为utf-8
spring.thymeleaf.mode=HTML5
# 配置视图解析器
spring.thymeleaf.prefix=classpath:/templates/
# 模板后缀, 默认为.html, 用于创建模板url "前缀" + 模板名称 + "后缀" 即可定位到具体模板
spring.thymeleaf.suffix=.html
# 默认模板解析器的执行顺序
#spring.thymeleaf.templates-resolver-order=
# 要解析的模板名称, 用逗号隔开
# spring.thymeleaf.view-names=

在html文件中加头部

1
2
3
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-4.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">

使用bootrap4.0版本

1
2
3
4
5
6
<script src="http://66.lacknb.cn/ssm/js/jquery3.3.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
crossorigin="anonymous"></script>

控制器如下

1
2
3
4
5
6
7
8
9
10
11
@RequestMapping("/demo01")
public String test01(ModelMap modelMap, HttpSession session){
modelMap.addAttribute("message", "<a href=\"#\" class=\"btn btn-primary\">thymeleaf 哈喽. </a>");
User user = new User();
user.setUid(11);
user.setUname("张三");
user.setUsex("女");
modelMap.addAttribute("user1", user);
session.setAttribute("user2", user);
return "demo01";
}

demo01.html

1
2
3
<h1 align="center" th:text="'这是我收到的第一条信息为: ' + ${message} + '---这是结尾'" >Hello World !!!</h1>

<h2 align="center" th:text="|这是第二种方式, 只不过限制有点多只能使用变量表达式--- ${message}---这是结尾|">Hello World !!!</h2>

运行之后发现没有显示HelloWorld , 而是被th:text中的字符串给替换了. 当我们不通过编译器, 直接通过浏览器打开demo01.html文件时, 我们会看到Hello World !!!. 对于springboot的静态资源, 我们放在src/java/resources/static文件夹下. 启动项目, 我们可以访问localhost:8080/静态资源文件名, 就可以访问到了.

th:text 与 th:utext的区别

1
2
3
<p>

</p>

utext 和 text的区别:
utext 会解析后台传过来的html标签
而text 不会解析, 它会把标签和内容一块显示到界面上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div class="max">
<div class="container">
<table class="table">
<tr>
<td th:text="姓名">1</td>
<td th:text="性别">2</td>
<td>3</td>
</tr>
<tr>
<td th:utext="|utext标签: ${message}|">1</td>
<td th:text="${user1.usex}">2</td>
<td th:text="|text标签: ${message}|">3</td>
</tr>
<tr th:object="${user1}">
<!--选择表达式 *{}-->
<td th:text="*{uname}">1</td>
<td th:text="${user1.usex}">2</td>
<td>4</td>
</tr>
</table>
</div>
</div>

*{} 与 ${} 的区别:

  1. 当没有用th:obejct指定对象前, 它们两个的用法完全一样
  2. 当指定对象之后, *{属性}可以直接获取属性,而${}不行, 只有${对象.属性}才能获取
  3. th:Object=”${session.user}” 这里用来指定对象, 只能是${}, 而*{}不能获取

链接网址

语法为: @{…}

​ 可以使用相对路径, 也可以使用绝对路径

例如:

  • 跳转到其他网页

    @{http://www.lacknb.cn}
  • get请求, 以及请求参数

    @{~/text/demo(id=1, uname='张三 ', usex='女')}

thymeleaf对url会自动帮我们编码, urlencode

1
2
3
4
5
<tr>
<td><a href="#" th:href="@{~/test/success.html}">点击跳转</a></td>
<td><a href="http://www.sohu.com" th:href="@{http://www.baidu.com}">跳转到百度还是搜狐</a></td>
<td><a href="#" th:href="@{/test/href.do(uid=1, uname='王二', usex='女的')}">获取json格式</a></td>
</tr>
1
2
3
4
@RequestMapping("/href.do")
public @ResponseBody User test02(User user){
return user;
}

编码后的url

1
<td><a href="/test/href.do?uid=1&amp;uname=%E7%8E%8B%E4%BA%8C&amp;usex=%E5%A5%B3%E7%9A%84">获取json格式</a></td>

js文件和css文件我们可以这样引入

1
2
3
4
5
<script src="http://66.lacknb.cn/ssm/js/jquery3.3.js" th:src="@{http://66.lacknb.cn/ssm/js/jquery3.3.js}"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" th:href="@{https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css}"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" th:src="@{https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js}" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
crossorigin="anonymous"></script>

服务器根目录相对URL

可以使用其他语法来创建相对于服务器根目录的URL(而不是上下文根目录的URL),以便链接到同一服务器中的不同上下文。这些网址的指定方式如下@{~/path/to/something}

1
<div th:if="${user.isAdmin()} == false"> ...

请注意,在上面的示例中,== falsey是写在花括号外面的,因此Thymeleaf本身负责它。如果将其写在花括号内,则OGNL / SpringEL引擎应负责:

算术运算

一些运算符存在文本别名:gt>),lt<),ge>=),le<=),not!)。还有eq==),neq/ ne!=)。

1
2
3
4
5
6
7
 <tr>
<!--这里的意思是 如果user1.uname 为null 输出李四, 不为空就输出user1.uname的值-->
<td th:text="*{user1.uname}?: '李四'">默认是张三</td>
<td>false</td>
<!--三目运算-->
<td th:class="4>0?5:9">false</td>
</tr>
1
2
3
4
5
6
7
8
9
10
<form action="#" th:attr="action=@{~/test/form.do}">
<!--
th:attr具有更改标签属性值的能力
-->
<fieldset>
姓名: <input type="text" class="form-control" name="uname"><br>
性别: <input type="text" class="form-control" name="usex"><br>
<input type="submit" class="btn btn-outline-primary" value="提交" th:attr="value='登录一下'">
</fieldset>
</form>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!--       一次设置多个属性怎么办?XML规则不允许您在标记中设置属性两次,因此th:attr将采用逗号分隔的分配列表,例如:-->
<table class="table">
<tr>
<td th:text="姓名">1</td>
<td th:text="性别">2</td>
<td>年龄</td>
</tr>
<tr>
<td><a th:attr="href=@{http://www.lacknb.cn}, target=@{_blank}">设置多个属性</a>
</td>
<td></td>
<td>2</td>
</tr>
</table>

迭代

th:each=” aaa : ${list} “

通过${aaa}(迭代变量), 获取其中的元素

1
2
3
4
5
<tr th:each="users : ${list}">
<td th:text="${users.uid}">id</td>
<td th:text="${users.uname}">姓名</td>
<td th:text="${users.usex}">性别</td>
</tr>

使用th:eachThymeleaf时,提供了一种可用于跟踪迭代状态的机制:状态变量 需要自己定义, 详细请看下面例子。

  • The current iteration index, starting with 0. This is the index property.
    • 当前迭代下标, 从0开始, 这是index属性
  • The current iteration index, starting with 1. This is the count property.
    • 当前迭代下标, 从1开始, 这是count属性
  • The total amount of elements in the iterated variable. This is the size property.
    • 迭代变量中元素的总数, 是size属性
  • The iter variable for each iteration. This is the current property.
    • 这是当前迭代的变量, (可以是对象), 是current属性
  • Whether the current iteration is even or odd. These are the even/odd boolean properties.
    • 判断当前迭代是偶数还是奇数, 返回布尔值, odd是奇数, even是偶数.
  • Whether the current iteration is the first one. This is the first boolean property.
    • 当前迭代是否是第一个元素
  • Whether the current iteration is the last one. This is the last boolean property.
    • 当前迭代的元素是否是最后一个元素, 返回布尔类型
1
2
3
4
5
<tr th:each="users, iterable : ${list}" th:class="${iterable.odd}">
<td th:text="${users.uid} + 'index: ' + ${iterable.index} + 'count: ' + ${iterable.count}">id</td>
<td th:text="${users.uname} + '当前:' + ${iterable.current} + '总数:' + ${iterable.size}">姓名</td>
<td th:text="${users.usex}">性别</td>
</tr>

这里iterable就是状态变量

基本对象

在jsp页面中, 我们可以很轻松地获取几个内置对象, 例如 request, session,等. 在thymeleaf的模板中. 也提供了类似的内置对象.

  • #ctx: 表示模板引擎的全局上下文对象
  • #vars: 同样返回模板引擎上下文对象, 一般使用#ctx即可
  • #locale: 在全局上下文中维护的java.util.Locale对象
  • #request: 表示HttpServletRequest对象
  • #response: 表示HttpServletResponse对象
  • #servletContext: 表示ServletContext对象

使用sequence方法

调用#numbers的sequence方法, 会返回integer数组, 该方法可以设置开始值, 结束值以及步长, 它主要有两个重载的方法

  • sequence(from , to) 设置开始值与结束值, 如果from比to大, 则步长默认为1, 否则步长为-1. 它的范围是 全是闭区间 即 [1, 3] 取 1, 2, 3
  • sequence(from , to , step): 设置开始值与结束值, 还有步长

例子: 在下方. from 和 to值 不能用${}获取, 可以使用#ctx.属性

1
2
3
4
5
6
7
8
<!-- 这里传过来的x是8-->
<ul class="pagination">
<li class="page-item"><a class="page-link" href="#">上一页</a></li>
<ul th:each="num : ${#numbers.sequence(1, #ctx.x)}" class="pagination">
<li class="page-item"><a class="page-link" href="#" th:text="${num}">1</a></li>
</ul>
<li class="page-item"><a class="page-link" href="#">下一页</a></li>
</ul>

效果如下:

MhNH0A.png

条件判断

th:if

    例如: 网页分页, 当我们数据量很大时, 需要对其进行分页. 从后台获取第一页的数据并获取到总页数, 我们根据这个总页数进行判断, 如果大于1 时候, 我们就在当前页面显示第2页的 按钮, 否则就不显示下一页的按钮.

1
2
3
4
5
<tr>
<td><span th:text="${x}">9999</span></td>
<td>评论</td>
<td><a href="#" th:href="@{~/comment(id=${x})}" th:text="|评论数: ${x}|" th:if="${x} > 0">点击进入</a></td>
</tr>

当x > 0就会显示超链接, 否则就不显示超链接

uri对象

#uri对象提供了对uri或url进行转码的功能, 其主要有以下四个方法

  • escapePathSegment(uri) 对uri路径进行编码, 大小写英文字母, 阿拉伯数字以及部分字符不会被转码. 这些字符包括: “ -._~!$ & &-amp; ‘ () +, ; = : @ “
  • escapePath(uri) 会编码的字符, 在前一个方法(escapePathSegment)的基础上增加一个 “/“
  • escapeFragemetnId(uri) 会被编码的字符, 在前一个方法(escapePath)的基础上, 多一个 “ ? “
  • escapeQueryParam(uri) 该方法主要对uri参数进行编码, 除了英文字母与数字之外, 还会对以下字符进行编码: “-.~!$*,;:@/?”

每一个编码的方法都三个派生出来 的方法, 以escapePath为例

  • escapePath(uri, encoding) 使用特定的字符集进行解码, 默认使用utf-8进行解码
  • unescapePath(uri) 对uri进行解码
  • unescapePath(uri, encoding) 使用特定的字符集进行解码 默认使用utf-8
-------------------本文结束 感谢您的阅读-------------------
坚持原创技术分享,您的支持将鼓励我继续创作!
0%