SpringBoot中Thymeleaf模板页面
本小记学习目标
-
关于Thymeleaf及编程起步
-
Thymeleaf静态资源处理
-
在模板页面中读取资源文件
-
Thymeleaf模板中对路径的处理
-
Thymeleaf模板中对内置对象的操作
-
Thymeleaf模板中对VO对象的展示
-
Thymeleaf模板页面中逻辑运算
-
Thymeleaf模板页面中数据遍历
-
页面包含指令
-
Thymeleaf数据处理
SpringBoot中除了可以进行Restful运行外,还可以和传统的MVC一样实现控制器与显示层的跳转,SpringBoot中所支持的显示层不仅仅是JSP页面,而是Thymeleaf模板页面。
一、关于Thymeleaf及编程起步
传统的JSP页面中会编写大量的Sriptlet程序,页面会显得混乱且非常不便于维护,JSP在后续提供了JSTL标签库,但是在页面的处理逻辑上还是比较复杂的。
为了解决上面这个问题,SpringBoot中引入了Thymeleaf模板,它是xml,xhtml,html5模板引擎,可以用于web和非web应用。
Thymeleaf提供了一种可以被浏览器正确显示(必须的)、格式良好的模板创建方式,可以通过它来创建经过验证的xml和html模板,开发时只需要把标签属性添加到模板中即可,这些标签属性会在DOM上执行预定义的逻辑,这样就简化了显示层的程序逻辑代码。
基础代码架构的搭建
1.在xiaoxieboot项目上右建--->New--->Maven Module
新增一个maven模块 xiaoxieboot-thymeleaf,以引入xiaoxieboot项目中的父pom信息
2.在xiaoxieboot-thymeleaf项目的pom.xml中新增依赖及打包方式的信息
<
dependencies
>
<!-- 添加对
thymeleaf
的依赖 -->
<
dependency
>
<
groupId
>org.springframework.boot
</
groupId
>
<
artifactId
>spring-boot-starter-
thymeleaf
</
artifactId
>
</
dependency
>
<
dependency
>
<
groupId
>
junit
</
groupId
>
<
artifactId
>
junit
</
artifactId
>
<
scope
>test
</
scope
>
</
dependency
>
<
dependency
>
<
groupId
>org.springframework.boot
</
groupId
>
<
artifactId
>spring-boot-starter-test
</
artifactId
>
<
scope
>test
</
scope
>
</
dependency
>
<
dependency
>
<
groupId
>org.springframework.boot
</
groupId
>
<
artifactId
>spring-boot-starter-web
</
artifactId
>
</
dependency
>
<
dependency
>
<
groupId
>org.springframework.boot
</
groupId
>
<
artifactId
>spring-boot-
devtools
</
artifactId
>
</
dependency
>
</
dependencies
>
<!-- 对项目打包发布处理 -->
<
build
>
<
finalName
>
xiaoxieboot-
thymeleaf
</
finalName
>
<
plugins
>
<
plugin
>
<
groupId
>org.springframework.boot
</
groupId
>
<
artifactId
>spring-boot-
maven-
plugin
</
artifactId
>
<
configuration
>
<!-- 配置程序执行的主类 -->
<
mainClass
>com.xiaoxie.SpringBootStartApplication
</
mainClass
>
</
configuration
>
<
executions
>
<
execution
>
<
goals
>
<
goal
>repackage
</
goal
>
</
goals
>
</
execution
>
</
executions
>
</
plugin
>
</
plugins
>
</
build
>
注意:这个里面的重点在于我们在对web的依赖下同时加入了对thymeleaf的依赖
3.新增一个Controller类,com.xiaoxie.controller.ThymeleafController
package com.xiaoxie.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public
class ThymeleafController {
@GetMapping(
"/view")
public String view(String
mid,Model
model) {
model.addAttribute(
"mid",
mid);
//request属性传递过来的
return
"message/message_show";
//默认跳转到message下的message_show.html
}
}
4.我们需要使用thymeleaf则需要在classpath中新增一个源码目录src/main/view
在STS(Eclipse)中如何添加新增源码目录?
在项目名上右键--->Build Path--->Configure Build Path...---> 先择Soruce、Add Folder...并在弹出的对话框中录入目录信息完成后点击Apply and Close
5.在上述新增的目录上新增一个包templates,在其下新增对应的html页面(一般来说我们会在templates下建立子包以把这些html文件做归类处理)
我们在templates包下新增一个子包,message,并在这个message包下新增一个html页面:message_show.html
注意:1,必须有一个包templates,页面必须要是html结尾的比如不可以是htm结尾的
一般来说我们不做默认配置的修改,如果非要修改我们可以类似如下做修改(在application.yml配置文件中修改)
spring:
thymeleaf:
suffix: .htm
#模板文件的后缀
prefix: classpath:/mytemplates/
#模板文件所在的目录前缀
6.message_show.html页面的信息如下
<!
DOCTYPE
html>
<!-- 引入一个命名空间 -->
<
head
>
<
meta
charset=
"UTF-8"
>
<
title
>SpringBoot模板渲染
</
title
>
</
head
>
<
body
>
<
p
th:text=
"'网址:' + ${url}"
/>
<
p
th:text=
"'用户名:' + ${mid}"
/>
</
body
>
</
html
>
注意:必须要先引入一个命名空间
htt://www.thymeleaf.org
${url}与${mid}是通过控制器传过来参数
th:text 这个表示显示文本内容(这个是纯文本的显示)
th:utext 这个是表示在显示文本内容时会对html元素做解析(也就是如果controller传过来的是一个html元素内容则需要使用utext)
7.在com.xiaoxie包下新增SpringBoot的启动类SringBootStartApplicatioin
package com.xiaoxie;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public
class SpringBootStartApplication {
public
static
void main(String[]
args) {
SpringApplication.
run(SpringBootStartApplication.
class,
args);
}
}
启动程序后访问如下链接:
http://localhost:8080/view?mid=xiaoxie 在页面中会显示不如下信息
网址:xiaoxie.com
用户名:xiaoxie
二、T
hymeleaf静态资源处理
对于静态资源,要求必须放在static目录中。
在view源码目录下我们新增一个目录:static
在static的目录下分别新增三个目录:css,images,js
css目录下新增一个style.css
.message {
background:
gray;
color:
white;
}
image目录下存入两个图片
logo.ico
Spring.png
js目录下新增一个js文件:index_console.js
window.onload =
function(){
console.log(
"Thymeleaf添加静态资源文件!");
}
在view源码目录下新增一个静态的html文档:message_index.html
<!
DOCTYPE
html>
<
head
>
<
meta
charset=
"UTF-8"
>
<
title
>
Thymeleaf模板渲染
</
title
>
<
link
rel=
"icon"
type=
"image/x-icon"
href=
"/images/logo.ico"
/>
<
link
rel=
"stylesheet"
type=
"text/css"
href=
"/css/style.css"
/>
<
script
type=
"text/javascript"
src=
"/js/index_console.js"
></
script
>
</
head
>
<
body
>
<
div
>
<
img
src=
"/images/Spring.png"
/>
</
div
>
<
div
class=
"message"
>
Thymeleaf添加静态资源文件!
</
div
>
</
body
>
</
html
>
启动SpringBoot,访问上面的这个静态html文件
http://localhost:8080/message_index.html
这里有一个关键的点就是必须要有一个static的目录
三、
在模板页面中读取资源文件
在模板页面中要读取资源文件有三个点
1.在Messages.properties属性文件中定义资源内容
2.在application.yml配置文件中定义资源文件
3.在模板页面中需要使用某个资源时通过#{key}的形式引用资源内容(这里需要动态页面的支持所以需要由Controller类作跳转而不是直接使用静态资源)
在src/main/resources下新增一个包i18n,并在其中添加资源文件Messages.properties
welcome.url=xiaoxie.com
welcome.msg=欢迎{0}!
注意:中文会在Eclipse中自动unicode编码,如果我们想显示为中文需要把这个文件的编码设置为utf-8的编码格式,点击文件右键--->Properties,在Text file encoding中选择Other并在下拉框中选择UTF-8
在src/main/resources下新增application.yml配置文件,在这个配置文件中定义资源文件
spring:
messages:
basename: i18n/Messages
在Controller类中新增一个方法,让其跳转到对应的thymeleaf模板页面
@GetMapping(
"/showMessage")
public String showMessage() {
return
"message/showMessage";
}
在这个方法中我们可以看到它要跳转到的模板面在message下的showMessage.html
新增showMessage.html页面
<!
DOCTYPE
html>
<
head
>
<
meta
charset=
"UTF-8"
>
<
title
>读取资源文件中内容
</
title
>
<
link
rel=
"icon"
type=
"image/x-icon"
href=
"/images/logo.ico"
/>
</
head
>
<
body
>
<
h2
th:text
=
"#{welcome.url}"
/>
<
h2
th:text
=
"#{welcome.msg('小谢')}"
/>
</
body
>
</
html
>
注意:1.读取资源的形式:#{key};2.当资源文件中的信息带参时的写法是#{key('值')};3.在模板页面中直接读取资源的值即可不需要在Controller中注入messageSrouce再借助getMessage方法读取资源的值后在Model中绑定好值再传入模板这种方式。
四、T
hymeleaf模板中对路径的处理
在Web开发中对于路径和处理相对来说操作繁琐的,要正确地定位路径则需要协议、主机、端口、虚拟目录的名称。
在JSP中我们常见的路径处理方式如下:
<%
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/";
%>
然后在页面中使用<base>元素引用上面的路径:<base href="<%=basePath%>"/>
在Thymeleaf中我们在动态页面中只需要使用"@{路径}"即可。
我们在控制器中新增一个方法:path
@GetMapping(
"/path")
public String path() {
return
"message/message_path";
}
从这个方法我们可以看到当我们访问/path时会跳转到message目录下的templates/message/message_path.html
新增message_path.html
<!
DOCTYPE
html>
<
head
>
<
meta
charset=
"UTF-8"
>
<
title
>Insert title here
</
title
>
<
link
rel=
"icon"
type=
"image/x-icon"
th:href=
"@{/images/logo.ico}"
/>
<
link
rel=
"stylesheet"
type=
"text/css"
th:href=
"@{/css/style.css}"
/>
<
script
type=
"text/javascript"
th:src=
"@{/js/index_console.js}"
></
script
>
</
head
>
<
body
>
<
div
><
img
th:src=
"@{/images/Spring.png}"
></
div
>
<
div
class=
"message"
>
Thymeleaf动态路径的处理
</
div
>
</
body
>
</
html
>
从上面对路径的处理可以看到它的处理形式是:@{路径}
它在引用路径的标签前加上了th:
五、
Thymeleaf模板中对内置对象的操作
在模板页面中最为常见的功能就是对于控制器传来的属性进行展示。Thymeleaf支持了内置对象的直接使用,也可以直接调用内置对象所提供的处理方法。
当通过控制器传递属性到Thymeleaf模板页面的时候,默认支持的属性获取范围是request,取属性的值的方法:
${属性名称}
如果需要接收其他属性范围的值,需要显示地指定范围,如:
${session.属性名称};${application.属性名称}
在Controller中新增两个控制器方法
@GetMapping(
"/getAttr")
public String getAttr() {
//获取HttpServletRequest内置对象
RequestAttributes
requestAttributes = RequestContextHolder.
getRequestAttributes();
HttpServletRequest
request = ((ServletRequestAttributes)
requestAttributes).getRequest();
//绑定属性值
return
"message/message_attr";
}
@GetMapping(
"/getAttr1")
public String getAttr1(HttpServletRequest
request) {
//绑定属性值
return
"message/message_attr";
}
这两个方法跳转到的模板页面都是templeates/message下的message_attr.html
message_attr.html
<!
DOCTYPE
html>
<
head
>
<
meta
charset=
"UTF-8"
>
<
title
>Insert title here
</
title
>
</
head
>
<
body
>
<
p
th:text=
"'request_url = ' + ${request_url}"
/>
<
p
th:text=
"'session_url = ' + ${session.session_url}"
/>
<
p
th:text=
"'application_url = ' + ${application.application_url}"
/>
</
body
>
</
html
>
启动SpringBoot,访问
http://localhost:8080/getAttr1或
http://localhost:8080/getAttr
在浏览器中显示的内容如下
request_url = request-xiaoxie.com
session_url = session-xiaoxie.com
application_url = application-xiaoxie.com
在Thymeleaf模板页面中也可以直接使用内置对象,修改message_attr.html
<!
DOCTYPE
html>
<
head
>
<
meta
charset=
"UTF-8"
>
<
title
>Insert title here
</
title
>
</
head
>
<
body
>
<
p
th:text=
"'request_url = ' + ${request_url}"
/>
<
p
th:text=
"'session_url = ' + ${session.session_url}"
/>
<
p
th:text=
"'application_url = ' + ${application.application_url}"
/>
<
hr
/>
<
h2
>直接使用内置对象
</
h2
>
<
p
th:text=
"${#httpServletRequest.getRemoteAddr()}"
/>
<
p
th:text=
"${#httpServletRequest.getAttribute('request_url')}"
/>
<
p
th:text=
"${#httpSession.getAttribute('session_url')}"
/>
<
p
th:text=
"${#httpSession.getId()}"
/>
<
p
th:text=
"${#httpServletRequest.getServletContext().getRealPath('/')}"
/>
</
body
>
</
html
>
六、
Thymeleaf模板中对VO对象的展示
在前面我们说了如何对内置对象的操作,在实际的开发过程中我们更多地的需要把封装的VO对象传到页面中进行展示,这个时候则可以使用绑定了VO对象的属性名称.对应属性名称,形式如下:
${属性名称.成员属性名称}
新增一个VO类,Employee
package com.xiaoxie.vo;
import java.util.Date;
public
class Employee {
private String
no;
//员工编号
private String
name;
//员工姓名
private String
post;
//员工所在岗位
private Date
joinDate;
//员工入职日期
private Double
salary;
//基本工资
public String getNo() {
return
no;
}
public
void setNo(String
no) {
this.
no =
no;
}
public String getName() {
return
name;
}
public
void setName(String
name) {
this.
name =
name;
}
public String getPost() {
return
post;
}
public
void setPost(String
post) {
this.
post =
post;
}
public Date getJoinDate() {
return
joinDate;
}
public
void setJoinDate(Date
joinDate) {
this.
joinDate =
joinDate;
}
public Double getSalary() {
return
salary;
}
public
void setSalary(Double
salary) {
this.
salary =
salary;
}
}
在控制器中新增一个方法
@GetMapping(
"/getEmp")
public String getEmp(Model
model)
throws Exception {
Employee
emp =
new Employee();
emp.setNo(
"0001");
emp.setName(
"小谢");
emp.setPost(
"研发工程师");
emp.setSalary(18500.00);
emp.setJoinDate(
new SimpleDateFormat(
"yyyy-MM-dd").parse(
"2021-01-20"));
//把
emp
绑定到model中
model.addAttribute(
"emp",
emp);
return
"message/message_employee";
}
这个控制器需要跳转到templates/message/message_employee.html,我们新增对应的html模板页面
<!
DOCTYPE
html>
<
head
>
<
meta
charset=
"UTF-8"
>
<
title
>员工信息
</
title
>
</
head
>
<
body
>
<
h2
>员工信息如下:
</
h2
>
<
table
border=
"1"
>
<
thead
>
<
tr
>
<
td
>员工编号
</
td
>
<
td
>员工姓名
</
td
>
<
td
>岗位
</
td
>
<
td
>薪资
</
td
>
<
td
>入职日期
</
td
>
</
tr
>
</
thead
>
<
tbody
>
<
tr
>
<!-- <td>${emp.no}</td> -->
<
td
><
text
th:text=
"${emp.no}"
/></
td
>
<
td
>
<
span
th:text
=
"${emp.name}"
/>
</
td
>
<
td
>
<
span
th:text
=
"${emp.post}"
/>
</
td
>
<
td
>
<
span
th:text
=
"${emp.salary}"
/>
</
td
>
<
td
>
<
span
th:text
=
"${emp.joinDate}"
/>
</
td
>
</
tr
>
</
tbody
>
</
table
>
</
body
>
</
html
>
注意:要让Thymeleaf中模板可以解析出来属性中的值形式必须是:${绑定的属性.属性的名称};不可以直接输出内容而要在对应的标签内输出值才能解析到,看上面<td>中注释的哪一行,它是无法解析到对应的属性值的。
从上面页面我们可以看到每次输出的时候都需要写一个${emp.XXX},thymeleaf中也提供了一睦土地局化的输出比如我们在需要输出元素的上级父节点上加上
th:object="${emp}",那么在实际解析值的地方只需要使用*{属性名}即可
比如上面的页面代码我们可以修改为如下:
<! DOCTYPE html>
<
head
>
<
meta
charset=
"UTF-8"
>
<
title
>员工信息
</
title
>
</
head
>
<
body
>
<
h2
>员工信息如下:
</
h2
>
<
table
border=
"1"
>
<
thead
>
<
tr
>
<
td
>员工编号
</
td
>
<
td
>员工姓名
</
td
>
<
td
>岗位
</
td
>
<
td
>薪资
</
td
>
<
td
>入职日期
</
td
>
</
tr
>
</
thead
>
<
tbody
th:object=
"${emp}"
>
<
tr
>
<!-- <td>${emp.no}</td> -->
<
td
><
text
th:text=
"*{no}"
/></
td
>
<
td
>
<
span
th:text
=
"*{name}"
/>
</
td
>
<
td
>
<
span
th:text
=
"*{post}"
/>
</
td
>
<
td
>
<
span
th:text
=
"*{salary}"
/>
</
td
>
<
td
>
<
span
th:text
=
"*{joinDate}"
/>
</
td
>
</
tr
>
</
tbody
>
</
table
>
</
body
>
</
html
>
七、Thymeleaf模板页面中逻辑运算
这里的逻辑处理包含如下:判断、循环……操作
在页面可以使用下面两类运算符
1.逻辑运算符:and,or
2.关系比较符:>,<,>=,<=,==,!=,lt,gt,le,ge,eq,ne
我们可以在message_employee.html页面未尾加上一些逻辑判断,在</table>标签后添加如下判断信息
<
div
th:object=
"${emp}"
>
<
p
th:if=
"*{post eq '研发工程师'}"
>
<
span
th:text=
"*{name}"
></
span
>,程序猿一枚!
</
p
>
<
p
th:if=
"*{post eq '产品经理'}"
>
<
span
th:text=
"*{name}"
></
span
>,产品狗一枚!
</
p
>
</
div
>
我们在使用th:if判断条件满足时,对于不满足的也可以使用th:unless来处理
<
div
th:object=
"${emp}"
>
<
p
th:if=
"*{post eq '研发工程师'}"
>
<
span
th:text=
"*{name}"
></
span
>,是程序员!
</
p
>
<
p
th:unless=
"*{post eq '研发工程师'}"
>
<
span
th:text=
"*{name}"
></
span
>,不是程序员!
</
p
>
</
div
>
switch-case,实现开关逻辑处理
<
div
th:object=
"${emp}"
>
<
p
th:switch=
"*{post}"
>
<
span
th:case=
"产品经理"
>产品经理
</
span
>
<
span
th:case=
"研发工程师"
>研发工程师
</
span
>
<
span
th:case=
"*"
>未知
</
span
>
</
p
>
</
div
>
th:case="*"表示没有匹配到时的情况
八、Thymeleaf模板页面中数据遍历
在Thymeleaf模板页面中可以使用th:each实现对List、Map集合的迭代输出。
在控制器类中新增方法返回List集合,然后通过request属性传递到页面中。
@GetMapping(
"/list")
public String listAllEmps(Model
model)
throws Exception {
List<Employee>
emps =
new ArrayList<Employee>();
Employee
emp =
new Employee();
emp.setNo(
"0001");
emp.setName(
"小谢");
emp.setPost(
"研发工程师");
emp.setSalary(18500.00);
emp.setJoinDate(
new SimpleDateFormat(
"yyyy-MM-dd").parse(
"2021-01-20"));
emps.add(
emp);
Employee
emp1 =
new Employee();
emp1.setNo(
"0002");
emp1.setName(
"小王");
emp1.setPost(
"产品经理");
emp1.setSalary(16500.00);
emp1.setJoinDate(
new SimpleDateFormat(
"yyyy-MM-dd").parse(
"2021-01-20"));
emps.add(
emp1);
Employee
emp2 =
new Employee();
emp2.setNo(
"0003");
emp2.setName(
"小李");
emp2.setPost(
"项目经理");
emp2.setSalary(19500.00);
emp2.setJoinDate(
new SimpleDateFormat(
"yyyy-MM-dd").parse(
"2021-01-20"));
emps.add(
emp2);
model.addAttribute(
"allemps",
emps);
return
"message/message_list";
}
在templates/message目录下新增一个模板页面:message_list.html
<!
DOCTYPE
html>
<
head
>
<
meta
charset=
"UTF-8"
>
<
title
>Insert title here
</
title
>
</
head
>
<
body
>
<
h2
>所有员工信息:
</
h2
>
<
table
border=
"1"
>
<
tr
>
<
td
>序号
</
td
>
<
td
>员工编号
</
td
>
<
td
>员工姓名
</
td
>
<
td
>岗位
</
td
>
<
td
>薪资
</
td
>
<
td
>入职日期
</
td
>
</
tr
>
<
tr
th:each=
"emp,empstat:${allemps}"
>
<
td
th:text=
"${empstat.index + 1}"
/>
<
td
th:text=
"${emp.no}"
/>
<
td
th:text=
"${emp.name}"
/>
<
td
th:text=
"${emp.post}"
/>
<
td
th:text=
"${emp.salary}"
/>
<
td
th:text=
"${emp.joinDate}"
/>
</
tr
>
</
table
>
</
body
>
</
html
>
Map集合的迭代的遍历
在控制器中新增控制器方法,返回所有员工的map集合。
@GetMapping(
"/map")
public String MapAllEmps(Model
model)
throws Exception {
Map<String,Employee>
emps =
new HashMap<String,Employee>();
Employee
emp =
new Employee();
emp.setNo(
"0001");
emp.setName(
"小谢");
emp.setPost(
"研发工程师");
emp.setSalary(18500.00);
emp.setJoinDate(
new SimpleDateFormat(
"yyyy-MM-dd").parse(
"2021-01-20"));
emps.put(
emp.getNo(),
emp);
Employee
emp1 =
new Employee();
emp1.setNo(
"0002");
emp1.setName(
"小王");
emp1.setPost(
"产品经理");
emp1.setSalary(16500.00);
emp1.setJoinDate(
new SimpleDateFormat(
"yyyy-MM-dd").parse(
"2021-01-20"));
emps.put(
emp1.getNo(),
emp1);
Employee
emp2 =
new Employee();
emp2.setNo(
"0003");
emp2.setName(
"小李");
emp2.setPost(
"项目经理");
emp2.setSalary(19500.00);
emp2.setJoinDate(
new SimpleDateFormat(
"yyyy-MM-dd").parse(
"2021-01-20"));
emps.put(
emp2.getNo(),
emp2);
model.addAttribute(
"allemps",
emps);
return
"message/message_map";
}
在templates/message下新增模板页面message_map.html
<!
DOCTYPE
html>
<
head
>
<
meta
charset=
"UTF-8"
>
<
title
>Insert title here
</
title
>
</
head
>
<
body
>
<
h2
>所有员工信息:
</
h2
>
<
table
border=
"1"
>
<
tr
>
<
td
>序号
</
td
>
<
td
>key
</
td
>
<
td
>员工编号
</
td
>
<
td
>员工姓名
</
td
>
<
td
>岗位
</
td
>
<
td
>薪资
</
td
>
<
td
>入职日期
</
td
>
</
tr
>
<
tr
th:each=
"empEntry,empstat:${allemps}"
>
<
td
th:text=
"${empstat.index + 1}"
/>
<
td
th:text=
"${empEntry.key}"
/>
<
td
th:text=
"${empEntry.value.no}"
/>
<
td
th:text=
"${empEntry.value.name}"
/>
<
td
th:text=
"${empEntry.value.post}"
/>
<
td
th:text=
"${empEntry.value.salary}"
/>
<
td
th:text=
"${empEntry.value.joinDate}"
/>
</
tr
>
</
table
>
</
body
>
</
html>
注意:对于Map集合,每一次迭代时所取出的对象类型是Map.Entry接口实例,然后在通过这个实例来获取key及value的值
九、页面包含指令
在页面的开发过程中,包含是一个重要的指令,使用包含可以实现页面代码的重利用来提高程序的开发效率,保障页面开发的规范一致性。Thymeleaf模板中提供了两种支持语法
1.th:replace:使用标签进行替换,原始的宿主标签还在,但是包含标签不在
2.th:include:进行包含,原始的宿主标签消失,只保留包含的标签
在templates下新增一个包:commons,并在其下新增一个footer页面
<!
DOCTYPE
html>
<
meta
charset=
"UTF-8"
>
<
foot
th:fragment=
"Copyright_info"
>
<
p
><
span
th:text=
"${info}"
></
span
></
p
>
</
foot
>
</
html
>
新增一个Controller方法,让它做动态跳转页面
@GetMapping(
"/include")
public String include(Model
model) {
return
"message/message_include";
}
在templates/message下新增一个页面message_include.html
<!
DOCTYPE
html>
<
head
>
<
meta
charset=
"UTF-8"
>
<
title
>Insert title here
</
title
>
</
head
>
<
body
>
<
div
th:include=
"@{/commons/footer}::Copyright_info"
th:with=
"info='小谢版权所有'"
></
div
>
</
body
>
</
html
>
注意:@{/commons/footer}是路径的表示方式::Copyright_info则是包含这个标签元素,th:with表示传入参数(info)
十、Thymeleaf数据处理
在Thymeleaf模板中我们还可以对集合、字符串、日期格式化等做数据处理操作。
对map元素在模板中进行判断
在message_map.html中添加如下代码
<!-- 对map操作 -->
<!-- 判断是否存在某个key -->
<
p
th:text=
"${#maps.containsKey(allemps,'0004')}"
/>
<!-- 根据key获取指定成员属性 -->
<
p
th:text=
"${allemps['0003'].name}"
/>
页面中会显示如下
false
小李
因为我们传过来的map中不包含0004这个key所以显示为false
map中key为0003的name属性值是小李
对Set集合中的元素判断
新增一个Controller方法,这个方法绑定一个set跳转到指定的页面
@GetMapping(
"/set")
public String set(Model
model) {
Set<String>
sets =
new HashSet<String>();
sets.add(
"刘备");
sets.add(
"关羽");
sets.add(
"张飞");
sets.add(
"诸葛亮");
model.addAttribute(
"sets",
sets);
return
"message/message_set";
}
新增一个message_set.html页面
<!
DOCTYPE
html>
<
head
>
<
meta
charset=
"UTF-8"
>
<
title
>Insert title
</
title
>
</
head
>
<
body
>
set集合的长度为:
<
span
th:text
=
"${#sets.size(sets)}"
/>
<
p
th:if=
"${#sets.contains(sets,'诸葛亮')}"
>存在有'诸葛亮'的信息
</
p
>
<
p
th:unless=
"${#sets.contains(sets,'赵云')}"
>不存在'赵云'的信息
</
p
>
</
body
>
</
html
>
对字符串的操作
在Controller类中新增一个方法,它绑定一个字符串,并跳转到指定的模板页面。
@GetMapping(
"/string")
public String string(Model
model) {
String
str =
" 这里是一个字符串!haha!Hello!";
model.addAttribute(
"str",
str);
return
"message/message_string";
}
新增一个message_string.html页面
<!
DOCTYPE
html>
<
head
>
<
meta
charset=
"UTF-8"
>
<
title
>Insert title here
</
title
>
</
head
>
<
body
>
<
p
th:text=
"${'原始字符串:' + str}"
/>
<
p
th:text=
"${'字符串替换:' + #strings.replace(str,'haha','hehe')}"
/>
<
p
th:text=
"${'字符串转大写:' + #strings.toUpperCase(str)}"
/>
<
p
th:text=
"${'字符串截取:' + #strings.substring(str,11)}"
/>
<
p
th:text=
"${'字符串去前后空格:' + #strings.trim(str)}"
/>
</
body
>
</
html
>
对日期时间格式化显示
我们修改一个之前返回员工map的页面,message_map.html,在模板页面中对于入职日期做格式化的显示
<
td
th:text=
"${#dates.format(empEntry.value.joinDate,'yyyy-MM-dd')}"
/>
在显示属性joinDate时前面加上了date的format方法把日期按指定的格式显示