于Thymeleaf官方介绍,Thymeleaf是一种现代的基于服务器端的Java模版引擎技术,它可以在web环境下使用,也可以在独立的、非Web环境下使用。对于目前流行的HTML5,Thymeleaf也是一种理想的选择。在SpringBoot中使用Thymeleafff非常简单,因为SpringBoot默认就是使用Thymeleaf作为视图层技术。所以,在SpringBoot中已经提供了Thymeleaf的默认配置,我们不需要进行额外配置。
官方网址:https://www.thymeleaf.org/
Github主页:https://github.com/thymeleaf/thymeleaf
一、下载和安装
在pom.xml文件中引入thymeleaf的依赖。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>1.5.6.RELEASE</version>
</dependency>
二、在SpringBoot中使用Thymeleaf
第一步:新建一个SpringBoot项目,并添加依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>1.5.6.RELEASE</version>
</dependency>
第二步:创建SpringMVC控制器
@Controller
public class HelloController {
@RequestMapping("/hello.do")
public String sayHello(Model model) {
model.addAttribute("name", "jacky");
return "userinfo";
}
}
第三步:新建一个html页面。在src/main/resources/templates目录下新建userinfo.html文件。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<title>Insert title here</title>
<style>
* {
font-size: 22px;
}
</style>
</head>
<body>
这是第一个使用Thymeleaf实现的页面。
</body>
</html>
注意:需要在html标签中指定xmlns:th=”http://www.thymeleaf.org”。
第四步:创建SpringBoot启动类。
@SpringBootApplication(scanBasePackages = {"com.xxyy.controller"})
public class Application {
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(Application.class);
springApplication.run(args);
}
}
三、获取上下文数据
在HTML标签中使用th:text属性:
<span th:text="${user.name}"></span>
<span th:text="*{user.name}"></span>
注意:1)th:text属性值支持OGNL表达式;2)如果指定了th:text属性,那么标签体内容将不会显示出来。
除此以外,如果要获取其他上下文数据(例如:Session数据),需要通过以下几个上下文变量来获取。
上下文变量 |
作用 |
param |
获取请求参数,返回一个数组 |
session |
获取session对象的属性 |
application |
获取ServletContext对象的属性 |
四、选定对象
正常情况下,${user.name}和*{user.name}的用法是一样的。它们的唯一区别是:如果在标签中选定对象后,使用*{}方式访问对象属性不需要写对象名。例如:
<div th:object="${user}">
姓名:<span th:text="*{name}"></span><br/>
年龄:<span th:text="*{age}"></span><br/>
</div>
当然,也可以使用${#object.属性名}方式访问user对象的属性。例如:
<div th:object="${user}">
姓名:<span th:text="${#object.name}"></span><br/>
年龄:<span th:text="${#object.age}"></span><br/>
</div>
五、条件判断
在thymeleaf模版中使用条件判断,可以在标签中指定th:if和th:unless属性。如果th:if属性值为true,才会输出标签内容,例如:
<span th:if="${gender == 'male'}">男</span> //代码1
<span th:if="not ${gender == 'male'}">女</span> //代码2
th:unless的作用与上面代码2的作用相同。所以,代码2也可以写成:
<span th:unless="${gender == 'male'}">女</span> //代码2
六、循环
循环需要在标签上指定th:each属性,例如:
<ul th:each=”对象别名:${数组或集合属性}”>
<li th:text=”${对象别名.属性名}”></li>
</ul>
1.遍历list集合
<ul th:each="user:${users}">
<li th:text="'姓名' + ${user.name} + ', 年龄:' + ${user.age}"></li>
</ul>
2. 遍历map集合
<ul th:each="user:${users}">
<li th:each="entry:${user}" th:text="'学号:' + ${entry.key} + ', 姓名:' + ${entry.value.name} + ', 年龄:' + ${entry.value.age}"></li>
</ul>
注意:每一个user其实就是一个entry对象。如果要访问entry对象的key和value,需要使用th:each来遍历它们。
3. 获取遍历过程信息
Thymeleaf使用“状态变量”保留遍历过程的状态信息,该变量需要定义在th:each属性中。它包含了以下数据:
index:当前遍历的索引值,从0开始;
count:当前遍历的索引值,从1开始;
size:需要遍历的元素个数;
current:当前遍历的元素;
even/odd:判断当前遍历是偶数还是奇数;
first:判断当前元素是否是第一个元素;
last:判断当前元素是否是最后一个元素;
<table border="1" width="300" cellspacing="0">
<!-- ${iterStat.odd}? 'odd' :用于判断是否是奇数行,如果是就输出odd -->
<tr th:each="user,iterStat:${users}" th:class="${iterStat.odd}? 'odd'">
<td th:text="${user.name}"></td>
<td th:text="${user.age}"></td>
</tr>
</table>
th:class指定标签的class属性。${iterStat.odd}用于判断当前行索引值是否奇数,如果是返回true,否则返回false。${iterStat.odd}? 'odd'表示如果当前行是奇数行,那么就返回odd,否则返回空。
七、模版布局
第一步:在src/main/resources/templates下新建footer.html文件,然后在文件中定义一个模版。
<div th:fragment="copy">
© 2011 The Good Thymes Virtual Grocery
</div>
上面在footer模版中定义了一个名为copy的代码片段。
第二步:在userinfo.html中引入footer模版中名为copy的代码片段。
<div th:include="footer :: copy"></div>
另外,定义模版时候也可以指定参数,例如:
<div th:fragment="copy(company)">
<p th:text="'© 2011 版权归' + ${company} + '所有'"></p>
</div>
在th:include包含模版时候指定参数,例如:
<div th:include="footer :: copy('广州图书馆')"></div>
注意:参数数量必须要匹配。
八、内嵌
尽管Thymeleaf提供的标准方言让我们能够实现所有的页面功能。但有时候人们宁愿按照传统方式直接在标签体中写ONGL表达式。例如:
<p>Hello, [[${session.user.name}]]!</p>
上面代码[[…]]中就是OGNL表达式。这与下面代码的作用是一样的。
<p>Hello, <span th:text="${session.user.name}">Sebastian</span>!</p>
如果要实现内嵌,我们必须要指定th:inline属性来激活该功能。例如:
<p th:inline="text">Hello, [[${session.user.name}]]!</p>
th:line属性的值有:text、javascript、none。如果需要在javascript中实现内嵌,那么就需要在script标签中指定th:inline=”javascript”。
<script th:inline="javascript">
/*<![CDATA[*/
...
var username = /*[[${session.user.name}]]*/ 'Sebastian';
...
/*]]>*/
</script>
九、表达式对象
表达式对象分为基本对象和实用对象。
基本对象包:
#ctx
: the context object.#vars:
the context variables.#locale
: the context locale.#httpServletRequest
: (only in Web Contexts) theHttpServletRequest
object.#httpSession
: (only in Web Contexts) theHttpSession
object.
实用对象有:
#dates
: utility methods forjava.util.Date
objects: formatting, component extraction, etc.#calendars
: analogous to#dates
, but forjava.util.Calendar
objects.#numbers
: utility methods for formatting numeric objects.#strings
: utility methods forString
objects: contains, startsWith, prepending/appending, etc.#objects
: utility methods for objects in general.#bools
: utility methods for boolean evaluation.#arrays
: utility methods for arrays.#lists
: utility methods for lists.#sets
: utility methods for sets.#maps
: utility methods for maps.#aggregates
: utility methods for creating aggregates on arrays or collections.#messages
: utility methods for obtaining externalized messages inside variables expressions, in the same way as they would be obtained using #{…} syntax.#ids
: utility methods for dealing with id attributes that might be repeated (for example, as a result of an iteration).
例如:格式化日期。
<div th:text="${#calendars.format(current, 'yyyy年MM月dd日 HH:mm:ss')}"></div>
附录:后台完整代码
@Controller
public class HelloController {
@RequestMapping("/hello.do")
public String sayHello(Model model, HttpServletRequest request) {
User user = new User("小明", 18);
model.addAttribute("user", user);
model.addAttribute("gender", "female");
request.getSession().setAttribute("name", "小宝");
request.getServletContext().setAttribute("name", "大宝");
HashSet<User> users = new HashSet<User>();
users.add(new User("aa", 11));
users.add(new User("bb", 12));
users.add(new User("cc", 13));
model.addAttribute("users", users);
/*User[] users = new User[]{
new User("aa", 11),
new User("bb", 22),
new User("cc", 33)
};
model.addAttribute("users", users);
Map<String, User> users = new HashMap<String, User>();
users.put("110", new User("aa", 12));
users.put("220", new User("bb", 13));
users.put("330", new User("cc", 14));
model.addAttribute("users", users);*/
Date current = new Date();
model.addAttribute("current", current);
return "userinfo";
}
}