SpringBoot从入门到精通—Thymeleaf模板引擎详解

1、引言

        在做WEB开发的时候,我们不可避免的要在前端页面之间进行跳转,中间进行数据的查询等等操作。我们在使用Spring Boot之前包括我在内其实大部分都是用的是JSP页面,可以说使用的已经很熟悉。但是我们在使用Spring Boot开发框架以后我们会发现一个致命的问题,就是SpringBoot对Jsp的支持可以说是惨不忍睹,因此官方推荐我们使用Thymeleaf模板引擎来解决问题。目前而言,当然模板引擎有很多,比如Velocity、Freemarker、等等,但是我这一直感觉thymeleaf相对于其他的来说好用的还是不少的。在这里我们就来了解一下thymeleaf这个模板引擎的用法!

2、什么是模板引擎?

        模板引擎是为了使用户界面业务数据(内容)分离而产生的,它可以生成特定格式的文档。用于网站的模板引擎(比如Thymeleaf模板引擎)就是将模板文件和数据通过模板引擎生成一个HTML文本。

        简单说,通过使用模板引擎,可以将后端的数据填充到前端写好的页面模板中,作用类似JSP。和Thymeleaf 类似的模板引擎还有 Velocity、FreeMarker ,它们完全可以替代 JSP 。

3、 Spring Boot中使用Thymeleaf模板引擎

SpringBoot中提供了对模板引擎的支持,并且SpringBoot也建议我们使用模板引擎,常用的Thymeleaf使用的方法很简单,首先在pom.xml文件中引入thymeleaf的starter

3.1 引入Thymeleaf模板引擎的POM依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

        一般Spring Boot引入的都是依赖文件的最新的版本,如果发现不是最新的依赖版本或者你想更改依赖的版本,可以在<properties>标签中修改,比如修改thymeleaf的版本为3.0.10版本

<properties>
   <!--切换thymeleaf版本-->
   <thymeleaf.version>3.0.10.RELEASE</thymeleaf.version>
    <!-- 布局功能的支持程序  thymeleaf3主程序  layout2以上版本 -->
  <thymeleaf-layout-dialect.version>2.2.2</thymeleaf-layout-dialect.version>
</properties>
3.2 使用Thymeleaf

        引入Thymeleaf的依赖后,我们就可以使用了。在学习Spring Boot时无论是啥新东西,我们都可以打开XxxxAutoConfigrationXxxxProperties,从中我们可以基本了解Spring Boot对这个东西的默认配置。好了我们来看看Thymeleaf的配置类

当然,我们也可以在Spring Boot的主配置文件中进行thymeleaf相关配置:

#thymeleaf有关设置
spring.thymeleaf.prefix=classpath:/templates
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.servlet.content-type=text/html
#关闭模板缓存,避免更新无效
spring.thymeleaf.cache=false

(1)在控制层写一个跳转到hello.html页面的处理器方法

package com.xust.iot.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Map;

@Controller
public class HelloController {

    @RequestMapping("/hello")
    public String toHello(Model model){
        model.addAttribute("msg","Hello Thymeleaf!");
        return "hello";
    }
}

(2)在html页面中导入thymeleaf名称空间,名称空间的导入不是必须的,但是导入后可以有提示,提示还是挺好用的。

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

(3).然后在页面只用Thymeleaf语法获取服务器响应的数据

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
                xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>hello</title>
</head>
<body>
<!--thymeleaf中的th:text 作用是将等号后面值写到标签体内,会覆盖原有的值-->
<h1 th:text="${msg}">这里显示欢迎信息</h1>
</body>
</html>

测试结果

4、Thymeleaf模板引擎的基本语法

4.1 Thymeleaf常用属性

下面列举一些Thymeleaf常用的属性,全部的属性还请参考Thymeleaf官方手册。Thymeleaf的属性都有一个优先级,优先级从1~8,数字越低优先级越高就会被先执行。(以下用order表示优先级大小)

1、th:text:设置当前元素的文本内容,相同功能的还用th:utext,两者的区别是前者会转义特殊字符,后者不会。order=7
2、th:value:设置当前元素的value值,类似修改指定属性的还有th:src,th:herf,优先级order=6
3、th:each:遍历循环元素,和th:value或th:value一起使用。order=2
4、th:if:条件判断,类似的还有th:unless ,th:switch,th:case 。order=3
5、th:insert:代码块引入,类似的还有th:replaceth:include,三者的区别较大,若使用不恰当会破坏html结构,常用于公共代码块提取的场景。优先级最高:order=1
6、th:fragment:定义代码块,方便被th:insert引用。优先级最低:order=8
7、th:object:声明变量,一般和*{}一起配合使用,达到偷懒的效果。优先级一般:order=4
8、th:attr:修改任意属性,实际开发中用的较少,因为有丰富的其他th属性帮忙,类似的还有th:attrappend,th:attrprepend。优先级一般:order=5

除了这些Thymeleaf定义的一些属性外,在HTML中所有的结点属性都可以使用th:属性名=值的方式来动态设定值,具体使用方法参考下面的例子。

4.2 Thymeleaf标准表达式语法
  • ${.....} 变量表达式(Variable Expressions)
  • #{.....} 消息表达式(Message Expressions)
  • @{.....} 链接表达式(Link URL Expressions)
  • ~{.....} 代码块表达式(Fragment Expressions)
  • *{.....} 选择变量表达式(Selection Variable Expressions)

1、${} 变量表达式

Thymeleaf的变量表达式使用的其实是OGNL表达式,变量表达式的功能非常丰富。

  • (1) 可以获取对象的属性、调用方法等(OGNL可以做的事他都可以做)
  • (2) 可以使用内置对象。官方手册上给的可以使用的内置对象如下:
#ctx : the context object.     上下文对象
#vars: the context variables.   上下文变量  
#locale : the context locale.    本地区域信息
//下面这是下web环境下才有效果的
#request : (only in Web Contexts) the HttpServletRequest object.  request对象
#response : (only in Web Contexts) the HttpServletResponse object. response对象  
#session : (only in Web Contexts) the HttpSession object.          session对象
#servletContext : (only in Web Contexts)the ServletContext object.   ServletContext对象
  • (3) 可以使用一些内置的工具对象(方法)
#execInfo : 正在处理的模板信息
#messages : 获取外部信息的内部变量的一个实用方法,同时也可以用#{...}获取
#uris : 针对URL或URI进行一些转码的方法
#conversions : 根据配置执行一些转换方法
#dates :  java.util.Date 的对象
#calendars : java.util.Calendar 的对象
#numbers : 数值格式化方法
#strings : 字符串格式化方法,常用的Java方法它都有
#objects : java中Object类的一些方法
#bools : 布尔方法,常用的方法有:isTrue,isFalse等
#arrays : 数组方法,常用的方法有:toArray,length,isEmpty,contains,containsAll等
#lists ,#sets: 集合方法,常用的方法有:toList,size,isEmpty,contains,containsAll,sort等
#maps : map对象方法,常用的方法有:size,isEmpty,containsKey,containsValue等
#aggregates : 在数组或集合中创建聚合的一些实用方法.
#ids : 用于处理可能重复的标识属性的使用方法,例如,作为迭代的变量。

2、*{} 选择表达式
对于变量我们还可以使用*{}来处理,它和${}在功能上是一样的。但是有一个重要的区别:*{}评估所选对象上的表达式而不是整个上下文。 也就是说,只要没有选定的对象,${}*{}语法就会完全相同。下面是官网给的一个例子,可以说明这个问题:

3、#{} 消息表达式:主要用于处理资源国际化的。
4、@{} 链接表达式
Thymeleaf中专门用于定义超链接的表达式。配合Thymeleaf中的th:href属性一起使用

  • 链接表达式@{}基本用法
<!--使用th:href="@{webjars/资源路径}"导入资源文件-->
<link th:href="@{/webjars/bootstrap/4.0.0/css/bootstrap.css}"/>
<link th:href="@{/webjars/bootstrap/4.0.0/css/bootstrap-grid.css}"/>
<link th:href="@{/webjars/jquery/3.3.1-1/jquery.js}">
<!--引入项目中static/css目下的me.css文件-->
<link th:href="@{/static/css/me.css}">
  • 链接表达式@{} 高级用法:动态拼接URL请求路径

比如要拼接一个如下的动态路径:127.0.0.1/article/index/{id}?articleType=xxx&page=xxx,其中id是项目中每篇文章的id,articleType是文章的类型,page是控制分页的参数,现在要在页面提供这么一个连接来实现分页。

<a th:if="${articleType==0}"
   th:href="@{/article/index/{id}(id=${user.getUserId()},articleType=0,page=${articlePages.getNextPage()})}">
	<button class="ui right labeled icon button" style="background: white !important;font-weight: 100 !important;"> 下一页
	</button>
</a>
<a th:if="${articleType!=0}" th:href="@{/article/index/{id}(id=${user.getUserId()},page=${articlePages.getNextPage()})}">
	<button class="ui right labeled icon button" style="background: white !important;font-weight: 100 !important;"> 下一页
	</button>
</a>

实现结果:

5、~{}代码块表达式
Thymeleaf中专门用于引用片段的表达式。经常配合th:insert 和th:replace属性使用,例如:

<div th:insert="~{msg}">一些消息</div>

<div th:with="frag=~{footer :: #main/text()}">
  <p th:insert="${frag}">
</div>

合理的使用代码块表达式可以极大的减少我们项目中的冗余代码,尤其是页面中的冗余代码。我们可以把几个页面中公共使用的代码抽象成一个片段,然后在页面需要的位置引入代码块即可,而且更厉害的是Thymeleaf可以把页面的的head部分或者是JS脚本部分抽取出来统一管理,这样当我们项目发生改变的时候只用改一处就可以了。

留言区

还能输入500个字符