基于springboot对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不用下面参数, 使用默认参数即可.
# 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文件中加头部
<!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版本
<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>
控制器如下
@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
<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/静态资源文件名, 就可以访问到了.
<p>
</p>
utext 和 text的区别:
utext 会解析后台传过来的html标签
而text 不会解析, 它会把标签和内容一块显示到界面上
<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>
#{main.title}
#{message.entrycreated(${entryId})} #{main.title}
#{message.entrycreated(${entryId})} main.title}
#{message.entrycreated(${entryId})}
<div th:object="${session.user}">
<p>Name: <span th:text="*{firstName}">Sebastian</span>.</p>
<p>Surname: <span th:text="*{lastName}">Pepper</span>.</p>
<p>Nationality:
<span th:text="*{nationality}">Saturn</span>.</p>
</div>
语法为: @{...}
可以使用相对路径, 也可以使用绝对路径
例如:
@{http://www.lacknb.cn}
@{~/text/demo(id=1, uname='张三 ', usex='女')}
thymeleaf对url会自动帮我们编码, urlencode
<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>
@RequestMapping("/href.do")
public @ResponseBody User test02(User user){
return user;
}
编码后的url
<td><a href="/test/href.do?uid=1&uname=%E7%8E%8B%E4%BA%8C&usex=%E5%A5%B3%E7%9A%84">获取json格式</a></td>
js文件和css文件我们可以这样引入
<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),以便链接到同一服务器中的不同上下文。这些网址的指定方式如下 @{~/path/to/something}
<div th:if="${user.isAdmin()} == false"> ...
请注意,在上面的示例中,== false
y是写在花括号外面的,因此Thymeleaf本身负责它。如果将其写在花括号内,则OGNL / SpringEL引擎应负责:
一些运算符存在文本别名:gt
(>
),lt
(<
),ge
(>=
),le
(<=
),not
(!
)。还有 eq
(==
),neq
/ ne
(!=
)。
<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>
<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>
<!-- 一次设置多个属性怎么办?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}(迭代变量), 获取其中的元素
<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:each
Thymeleaf时,提供了一种可用于跟踪迭代状态的机制:状态变量 需要自己定义, 详细请看下面例子。
index
property.
count
property.
size
property.
current
property.
even/odd
boolean properties.
first
boolean property.
last
boolean property.
<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的模板中. 也提供了类似的内置对象.
调用#numbers的sequence方法, 会返回integer数组, 该方法可以设置开始值, 结束值以及步长, 它主要有两个重载的方法
例子: 在下方. from 和 to值 不能用${}获取, 可以使用#ctx.属性
<!-- 这里传过来的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>
效果如下:
th:if
例如: 网页分页, 当我们数据量很大时, 需要对其进行分页. 从后台获取第一页的数据并获取到总页数, 我们根据这个总页数进行判断, 如果大于1 时候, 我们就在当前页面显示第2页的 按钮, 否则就不显示下一页的按钮.
<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或url进行转码的功能, 其主要有以下四个方法
每一个编码的方法都三个派生出来 的方法, 以escapePath为例