thymeleaf基本语法

Spring Boot整合Thymeleaf 模版

SpringBoot项目默认不是JSP,那如何来实现我们的动态页面呢?SpringBoot推荐模板引擎Thymeleaf。其实JSP也属于一种模板引擎,比较常用的还有freemaker。模板引擎非常多,道理都一样

依赖

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

spirngboot默认配置了Thymeleaf
也可以自己写

spring:
  thymeleaf:
    prefix: classpath:/templates/
    suffix: .html
    mode: HTML
    encoding: UTF-8

如果希望客户端可以直接访问 HTML 资源,将这些资源放置在 static 路径下即可,否则必须通过 Handler 的后台映射才可以访问静态资源。

注意使用时一定别忘了导入命名空间

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

</body>
</html>

创建模板文件

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" >
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<p th:text="${msg}"></p>
    <!-- 方式1 -->
    <p th:text="'提示:'+${msg}"></p>
     <!-- 方式2 -->
    <p> 提示:[[${person.name}]] </p>   
    
</body>
</html>
  • <html xmlns:th="http://www.thymeleaf.org">是引入thymeleaf的命名空间,必须。

  • 可以在原来的任何属性前面加上前缀th:*来表示thymeleaf的定义。data-th-*效果一样。

  • 在标签内拼接字符串比较麻烦,可以在里面通过[[]]来显示跟拼接

定义页面

classpath:templates路径下创建html文件作为显示页面,一定要放在此路径,并且一定要是html格式,比如hello.html

简单表达式

Thymeleaf 提供了非常丰富的标准表达式语法,总共有 8 大类:

  • 简单表达式

  • 字面值

  • 文本操作

  • 算术运算

  • 布尔运算

  • 比较和相等

  • 条件运算

  • 无操作符

语法名称描述作用
${…}Variable Expressions变量表达式取出上下文变量的值
*{…}Selection Variable Expressions选择变量表达式取出选择的对象的属性值
#{…}Message Expressions消息表达式使文字消息国际化,I18N
@{…}Link URL Expressions链接表达式用于表示各种超链接地址
~{…}Fragment Expressions片段表达式引用一段公共的代码片段

Thymeleaf 常用语法

定义局部变量

使用th:with属性可以定义局部变量

 <span th:with="myName='dyk'">
   <p th:text="${myName}" ></p>
</span>

同时定义多个局部变量时,用英文,号分隔开

<p th:with="name=${user.name},age={user.age}">
    ......
</p>

注释

标准注释
  • 标准注释会在文件源代码中显示出来。

<!-- --->

析器级注释
  • 注释的代码块会在引擎解析的时候抹去。

    <!--/* ... */-->

取值

和原来jsp的el表达式类似

package com.blb.springbootmybatis.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class ThymeleafController {
    @GetMapping("/test1")
    public ModelAndView test(){
        ModelAndView modelAndView=new ModelAndView();
        modelAndView.addObject("name","dyk");
        modelAndView.setViewName("test");
        return modelAndView;
    }
}

<!--th:text就是将div中的内容设置为它指定的值,和Vue有点像
一样-->
<div th:text="${name}"></div>

拼接

<div th:text="'我的名字是'+${name}+'年龄是'+18"></div>

单引号加+号拼接
或者直接双引号里面使用| 拼接的内容 |

<div th:text="|我叫${name}|"></div>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div th:text="${name}"></div>
<div th:text="'我的名字是'+${name}+'年龄是'+18"></div>
<div th:text="|我叫${name}|"></div>
</body>
</html>

*{…}

变量表达式${}是面向整个上下文的,而选择变量表达式*{}的上下文是父标签(th:object)所选择的对象。

// Person bean
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Person {

	private String name ;
	private String sex ;
	private Integer age ;

}
// controller
@RequestMapping("/hello")
public String welcome(Model model){
    Person person = new Person("dyk","男",18);
    model.addAttribute("person",person);
    return "hello" ;
}
<span th:object="${person}">
   <p th:text="*{name}"></p>
   <p th:text="*{sex}"></p>
   <p th:text="*{age}"></p>
</span>
<!-- 跟下面效果等效 -->
<span >
    <p th:text="${person.name}"></p>
	<p th:text="${person.sex}"></p>
    <p th:text="${person.age}"></p>
</span>

内联表达式

内联表达式允许我们直接在 HTML 文本中使用标准表达式,而不需要使用th:*标签属性

[[ ]]

[[]]相当于th:text,对含有 HTML 标签的内容自动进行字符转义

<p>[[${msg}]]</p>
[( )]

[()]相当于th:utext,对含有 HTML 标签的内容不进行字符转义

<p>[(${msg})]</p>
th:inline

我们已经了解到,使用[[]][()]语法可以直接在 HTML 文本中使用标准表达式,如果想要使用更多高级的功能,需要使用th:inline属性来激活,它的取值如下

描述
none禁止内联表达式,可以原样输出 [[]] 和 [()] 字符串
text文本内联,可以使用 th:each 等高级语法
css样式内联,如<style th:inline="css">
javascript脚本内联,如:<style th:inline="javascript">
  • none

    <!-- [[ ]]不会被解析,原字符串输出 --> 
    <p th:inline="none">[[asdfsafd]]</p>
    
  • text

    <p th:inline="text">[[${msg}]]</p>
    
  • css

    <style th:inline="css">
        body {
            background-color:[[${bgColor}]];
        }
    </style>
    

字面值

所谓字面值,首先它不是一个变量,它是一个具体的确切的值,通常这些值是比较简单的,例如:18'welcome'等,它们没有名称,以至于我们只能用值来称呼它们,因此我们称其为字面值

文字字面值
  • 文字字面值是用单引号引起来的任何字符内容,如果字符内容里面含有单引号,则需要进行转义
<p th:text="'Welcome to bailiban...'"></p>
数字字面值
<!-- 2019 -->
<p th:text="2019"></p>
<!-- 2020 -->
<p th:text="2019 + 1"></p>
布尔字面值
<!-- false -->
<p th:text="true"></p>
<!-- false -->
<p th:text="1 > 2"></p>
<!-- 否 -->
<p th:text="1 > 2 ? '' : ''"></p>
空字面值
<!-- false -->
<p th:text="${user == null}"></p>
字符串连接

不管是字面值还是表达式的结果,我们都可以使用+符号将它们连接起来:

<p th:text="'Welcome to ' + ${msg} + '!'"></p>
字面值替换

符号||可以用来将字面值和表达式包裹起来,这样就能方便的替换变量的值,而不需要使用+连接符:

<p th:text="|Welcome to ${msg} !|"></p>
算术运算

支持+(加)、-(减)、*(乘)、/(除)、%(模)运算。

<!-- 6 -->
<p th:text="4 + 2"></p>
<!-- 2 -->
<p th:text="4 - 2"></p>
<!-- 8 -->
<p th:text="4 * 2"></p>
<!-- 2 -->
<p th:text="4 / 2"></p>
<!-- 0 -->
<p th:text="4 % 2"></p>
<!-- 2 -->
<p th:text="${page + 1}"></p>
<!-- 2 -->
<p th:text="${page} + 1"></p>
布尔运算

支持and(且)、or(或)、!(非)、not(非)运算

<!--true-->
<p th:text="${true and true}"></p>
<!--true-->
<p th:text="${true or false}"></p>
<!--false-->
<p th:text="${!true}"></p>
<!--true-->
<p th:text="${not false}"></p>
比较运算

支持<lt)、>gt)、<=le)、>=ge)、==eq)、!=ne

<p th:text="${person.age < 60}"></p>
<p th:text="${person.age <= 60}"></p>
<p th:text="${person.age > 18}"></p>
<p th:text="${person.age >= 18}"></p>
<p th:text="${person.age == 18}"></p>
<p th:text="${person.age != 18}"></p>
  • gt great than 大于
  • ge great equal 大于等于
  • eq equal 等于
  • lt less than 小于
  • le less equal 小于等于
  • ne not equal 不等于
三元运算

(if) ? (then) : (else)

<input th:value="${name == 'dyk'? '':'不是'}"/>

<div th:text="${age >= 20? '青年':'少年'}"></div>

<div th:text="${age ge 20? '青年':'少年'}"></div>

<p >[[${person.age >= 18?'成年':'未成年'}]]</p>

二元运算符

(value) ?: (defaultValue) 其中,value非空(null)即真,条件为真时输出value,否则输出defaultValue

<p th:text="${person.name}?:'用户名不能为空'"></p>

也可以使用无操作符达到相同效果。_表示显示标签体内的内容。

<p th:text="${person.name}?:_">用户名不能为空</p>

使用文本

th:text

在标签体中展示表达式评估结果的文本内容

<p th:text="${message}">Welcome to bailiban!</p>

当它作为静态文件直接运行时,浏览器会自动忽略它不能识别的th:text属性,而显示标签体的文本内容Welcome to bailiban!当它作为模板文件运行在服务器端时,th:text属性的具体值将会替换标签体的文本内容

th:utext

utexttext的区别是utext会解析html标签,而text不会。

假设model.addAttribute("msg","<b>welcome to bailiban ...</b> ");

<!--<b>welcome to bailiban ...</b> -->
<p th:text="${msg}"></p>
<!-- 显示welcome to bailiban ...,字体变粗,解析b标签的结果-->
<p th:utext="${msg}"></p>

设置属性

在 Thymeleaf 模板文件中,你可以使用th:*(或者使用th:attr属性)来设置任意的 HTML5 标签属性的值。不仅如此,你还可以th:*-*来同时为多个不同的标签属性设置相同的一个值,甚至你可以使用th:attrappendth:attrprepend来追加新的值到现有的标签属性值中

th:attr

这种方式是不被推荐的,了解一下就行。下面是用th:attr="href=..."来设置标签href属性的值

<a th:attr="href=@{https://www.google.com}">谷歌一下你就知道</a>
th:*

th:attr不够简洁,我们推荐下面的方式

<a th:href="@{https://www.google.com}">谷歌一下你就知道</a>

其中的*可以是HTML5中的任意属性

th:*-*

如果想要同时为标签的多个不同属性设置相同的一个值,可以使用th:*-*的语法

<img src="logo.png" th:alt-title="LOGO图片">

它相当于:

<img src="logo.png" th:alt="LOGO图片" th:title="LOGO图片">
th:attrappend & th:attrprepend
<!-- <button class="btn  disable ">购买</button> -->
<button class="btn" th:attrappend="class=' disable '">购买</button>
<!-- <button class=" disable btn">购买</button> -->
<button class="btn" th:attrprepend="class=' disable '">购买</button>
布尔属性

在 HTML 中有些属性是布尔属性,布尔属性是指没有值的属性,如readonlycheckedselected等。它们若存在那就意味着值为 true。 Thymeleaf 也允许我们通过th:*(这里的*表示任意的布尔属性) 来选择是否使用这些布尔属性

<input type="checkbox" th:checked="${remember}" /> 记住我

${remember}为null就不会默认选中,不为null则会默认勾选上

条件判断

th:if

th:if 表示条件成立时显示内容
当表达式的评估结果为真时则显示内容,否则不显示

<div th:if="${name=='dyk'}" th:text="${name}"></div>
<div th:if="${name=='dyk'}" >[[${name}]]</div>

取值也可以不写在标签里面,通过两个中括号

th:unless

th:unless 表示条件不成立时显示内容
th:unlessth:if判断恰好相反,当表达式的评估结果为假时则显示内容,否则不显示

<div th:unless="${name=='cb'}" th:text="${name}"></div>
<div th:unless="${name=='cb'}">[[${name}]]</div>

由于我存的name值是dyk不等于cb所以会取出来

th:swith

多路选择语句,它需要搭配th:case来使用:

switch

@GetMapping("/switch")
public String switchTest(Model model){
    model.addAttribute("gender","女");
    return "test";
}
<div th:switch="${gender}">
  <p th:case=""></p>
  <p th:case=""></p>
  <p th:case="*">未知</p>
</div>
<div th:switch="${person.sex}">
     <p th:case="男">man</p>
     <p th:case="女">girl</p>
</div>

循环遍历

遍历(迭代)的语法th:each="自定义的元素变量名称 : ${集合变量名称}"

<table border="1px solid #000">
    <tr>
     <th>id</th>
    <th>username</th>
    <th>password</th>
    <th>hobby</th>
    <th>email</th>
     <th>操作</th>
    </tr>

        <tr  th:each="user:${users}">
            <td th:text="${user.id}"></td>
            <td th:text="${user.username}"></td>
            <td th:text="${user.password}"></td>
            <td th:text="${user.hobby}"></td>
            <td th:text="${user.email}"></td>
        </tr>
    </th>
</table>

  • 属性th:each提供了一个用于跟踪迭代的状态变量,stat 状态变量的使用语法:th:each="自定义的元素变量名称, 自定义的状态变量名称 : ${集合变量名称}" 。 它包含以下几个属性 :
属性类型描述
indexint当前迭代的索引,从 0 开始
countint当前迭代的计数,从 1 开始
sizeint集合中元素的总个数
currentint当前的元素对象
evenboolean当前迭代的计数是否是偶数
oddboolean当前迭代的计数是否是奇数
firstboolean当前元素是否是集合的第一个元素
lastboolean当前元素是否是集合的最后一个元素
各行变色表格
<table border="1px solid #000">
    <tr>
     <th>id</th>
    <th>username</th>
    <th>password</th>
    <th>hobby</th>
    <th>email</th>
     <th>操作</th>
    </tr>

        <tr  th:each="user,stat:${users}" th:style="'background-color:'+@{${stat.odd}?'#F2F2F2'}">
            <td th:text="${user.id}"></td>
            <td th:text="${user.username}"></td>
            <td th:text="${user.password}"></td>
            <td th:text="${user.hobby}"></td>
            <td th:text="${user.email}"></td>
            <td>
                <a href="/toAddPage">添加</a>
                <a href="/delete/${user.id}">删除</a>
                <a href="/toUpdatePage/${user.id}">修改</a>
            </td>
        </tr>
    </th>
</table>

URL @{…} 链表表达式

Thymeleaf 对于 URL 的处理是通过 @{...} 进行处理,结合 th:href 、th:src

绝对地址

<a th:href="@{http://www.baidu.com}" th:text="baidu"></a>

相对地址

<!-- 不带参数 -->
<a th:href="@{hello2}" th:text="hello2"></a>  <br/>
<!-- 带参数 -->
<a th:href="@{hello2(name=${person.name},password='123')}" th:text="hello2"></a>  <br/>
  • 页面跳转必须通过后台controller
  • 参数都放在()括号内,参数之间用号隔开
  • 参数值变量通过${}引用
<a th:href="@{http://www.baidu.com}">跳转</a>
<a th:href="@{http://localhost:9090/index/url/{na}(na=${name})}">跳转2</a>
<img th:src="${src}">
<div th:style="'background:url('+ @{${src}} +');'">
<br/>
<br/>
<br/>
</div>

复用代码片段~{…}

~{…}片段表达式主要用来引用一段可重复使用的代码片段

  • base/common.html
<div th:fragment="foot-copy" >
    Copyright © 2012-2019 管理系统 - Version V1.1
</div>
  • hello.html
<div th:insert="~{base/common::foot-copy}"></div>
    • base/common是文件路径,foot-copy是定义的th:fragment值,用::分割。
  • ~{}可以省略。
    除了使用th:fragment还可以通过选择器来引用。

  • base/common.html

<div class="foot-copy" >
    Copyright © 2012-2019 管理系统 - Version V1.1
</div>
  • hello.html
<div th:insert="~{base/common::.foot-copy}"></div>

.foot-copy是CSS选择器去匹配。

我们定义代码片段时还可以声明一组参数:

  • base/common.html
<div th:fragment="menu(menuName1, menuName2)">
    <p th:text="${menuName1}"></p>
    <p th:text="${menuName2}"></p>
</div>
  • hello.html
<div th:insert="~{base/common::menu('用户中心', '我的订单')}"></div>

th:insertth:replace的区别?

​ 他们都是用来使用代码片段, th:insert 如同插入的字面意思,将指定的代码片段插入主标签内 。 th:replace 如同替换的字面意思,将主标签替换为指定的代码片段。

基本对象

对象描述
#ctx上下文对象
#vars同 #ctx,表示上下文变量
#locale上下文本地化(特定的地理区域)变量,可参考 java.util.Locale
#requestHttpServletRequest 对象,可参考 javax.servlet.http.HttpServletRequest
#responseHttpServletResponse 对象,可参考 javax.servlet.http.HttpServletResponse
#sessionHttpSession 对象,可参考 javax.servlet.http.HttpSession
#servletContextServletContext 对象,可参考 javax.servlet.ServletContext

#request

<!-- HTTP/1.1 -->
<p th:text="${#request.protocol}"></p>
<!-- http -->
<p th:text="${#request.scheme}"></p>
<!-- localhost -->
<p th:text="${#request.serverName}"></p>
<!-- 8080 -->
<p th:text="${#request.serverPort}"></p>
<!-- GET -->
<p th:text="${#request.method}"></p>
<!-- /hello -->
<p th:text="${#request.requestURI}"></p>
<!-- http://localhost:8080/hello -->
<p th:text="${#request.requestURL}"></p>
<!-- /hello -->
<p th:text="${#request.servletPath}"></p> 
<!-- zhangsan -->
<p th:text="${#request.getAttribute('student').name}"></p>
<!-- name=zhang  -->
<p th:text="${#request.queryString}"></p>

#response

<!-- 200 -->
<p th:text="${#response.status}"></p>
<!-- 8192 -->
<p th:text="${#response.bufferSize}"></p>
<!-- UTF-8 -->
<p th:text="${#response.characterEncoding}"></p>
<!-- text/html;charset=UTF-8 -->
<p th:text="${#response.contentType}"></p>

#session

<!-- 需要在后台开启会话,存入person数据 -->
<!-- BFE8F9E54C863E128B107532A902E921 -->
<p th:text="${#session.id}"></p>
<!-- 1499786693244 -->
<p th:text="${#session.lastAccessedTime}"></p>
<!-- seven -->
<p th:text="${#session.getAttribute('person').name}"></p>
@GetMapping("/object")
public String object(HttpServletRequest request){
    request.setAttribute("request","request对象");
    request.getSession().setAttribute("session","session对象");
    return "test";
}
<p th:text="${#request.getAttribute('request')}"></p>
<p th:text="${#session.getAttribute('session')}"></p>
<p th:text="${#locale.country}"></p>

内嵌对象

可以直接通过 # 访问。

对象作用
datesjava.util.Date 的功能方法
calendarsjava.util.Calendar 的功能方法
numbers格式化数字
stringsjava.lang.String 的功能方法
objectsObject 的功能方法
bools对布尔求值的方法
arrays操作数组的功能方法
lists操作集合的功能方法
sets操作集合的功能方法
maps操作集合的功能方法
@GetMapping("/util")
public String util(Model model){
    model.addAttribute("name","zhangsan");
    model.addAttribute("users",new ArrayList<>());
    model.addAttribute("count",22);
    model.addAttribute("date",new Date());
    return "test";
}
<!-- 格式化时间 -->
<p th:text="${#dates.format(date,'yyyy-MM-dd HH:mm:sss')}"></p>
<!-- 创建当前时间,精确到天 -->
<p th:text="${#dates.createToday()}"></p>
<!-- 创建当前时间,精确到秒 -->
<p th:text="${#dates.createNow()}"></p>
<!-- 判断是否为空 -->
<p th:text="${#strings.isEmpty(name)}"></p>
<!-- 判断List是否为空 -->
<p th:text="${#lists.isEmpty(users)}"></p>
<!-- 输出字符串长度 -->
<p th:text="${#strings.length(name)}"></p>
<!-- 拼接字符串 -->
<p th:text="${#strings.concat(name,name,name)}"></p>
<!-- 创建自定义字符串 -->
<p th:text="${#strings.randomAlphanumeric(count)}"></p>
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值