Thymeleaf

第一部分 认识Thymeleaf

什么是 Thymeleaf ?

Thymeleaf是一个现代服务器端Java模板引擎,适用于Web和独立环境,能够处理HTML,XML,JavaScript,CSS甚至纯文本。

Thymeleaf可以处理的模板?

  • HTML
  • XML
  • Text
  • JavaScript
  • CSS
  • RAW

两种标记模板模式 (HTML和XML)、三种文本模板模式 (Text,JavaScript,CSS ) 和一种无操作模板模式(RAW)

模板引擎的基本工作原理

在这里插入图片描述

1. 第一个Thymeleaf程序

  • 创建一个非Web项目

导入依赖

<dependency>
	<groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf</artifactId>
    <version>3.0.15.RELEASE</version>
</dependency>

静态数据

HelloThymeleaf.java

public class HelloThymeleaf{
    
    public static void main(String[] args){
        //创建模板引擎
        TemplateEngine engine = new TemplateEngine();
        //准备模板
        String input = "<input type='text' th:value='hellothymeleaf'/>";
        //准备数据,使用Context
        Context context = new Context();
        //调用引擎,处理模板和数据
        String out = engine.process(input,context);
        System.out.println("result:"+out);
    }
}

在这里插入图片描述

获取动态数据

HelloThymeleaf.java

public class HelloThymeleaf{
    
    public static void main(String[] args){
        //创建模板引擎
        TemplateEngine engine = new TemplateEngine();
        //准备模板
        String inStr = "<input type='text' th:value='${name}'/>";
        //准备数据,使用Context
        Context context = new Context();
        context.setVariable("name","lisi");
        //调用引擎,处理模板和数据
        String out = engine.process(inStr,context);
        System.out.println("result:"+out);
    }
}

在这里插入图片描述

2. 使用模板文件

在main目录下创建resources包,在resources中添加main.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <input type="text" th:value="${name}" />
</body>
</html>

HelloThymeleaf.java

public class HelloThymeleaf{
    
    public static void main(String[] args){
        
        //创建模板引擎
        TemplateEngine engine = new TemplateEngine();
        //读取磁盘中的模板文件
        ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();
        //设置引擎使用resovler
        engine.setTemplateResolver(resolver);
        //指定数据
        Context context = new Context();
        context.setVariable("name","lisi");
        //处理模板
        String out = engine.process("main.html",context);
        System.out.println("result:"+out);
    }
}

在这里插入图片描述

3. 设置模板前后缀

在resources目录下创建文件夹templates

创建index.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <input type="text" th:value="${name}" />
</body>
</html>

HelloThymeleaf.java

public class HelloThymeleaf{
    
    public static void main(String[] args){
        
        //创建模板引擎
        TemplateEngine engine = new TemplateEngine();
        //读取磁盘中的模板文件
        ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();
        
        //设置前缀
        resolver.setPrefix("templates/");
        //设置后缀
        resolver.setSuffix(".html");
        //设置引擎使用resovler
        engine.setTemplateResolver(resolver);
        //指定数据
        Context context = new Context();
        context.setVariable("name","lisi");
        //处理模板
        String out = engine.process("index",context);
        System.out.println("result:"+out);
    }
}

4. SpringBoot中使用Thymeleaf

  1. 创建springboot项目,导入依赖
<dependency>
	<groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
  1. 编写application.properties
# 指定模板引擎主要处理的文件格式
spring.thymeleaf.mode=HTML
#指定模板文件所存放的位置 默认:classpath:/templates/
spring.thymeleaf.prefix=classpath:/templates/
# 指定模板文件的后缀名
spring.thymeleaf.suffix=.html
#不使用模板的缓存,每次都是用最新的模板数据
spring.thymeleaf.cache=false
  1. 编写controller文件

HelloController.java

@Controller
public class HelloController{
    /*
    	参数:Model 可以存放数据,放到request作用域中
    	返回值: String:表示试图
     */
    @RestMapping("/hello")
    public String hello(Model model){
        //添加数据
        model.addAttribute("name","lisi");//指定模板视图
        return "index";
    }
    
} 
  • 不使用Model,可以使用HttpServletRequest,用request.attAttribute(“name”,”lisi”);
  1. 创建index.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="${name}"></p>
</body>
</html>

第二部分 表达式语法

1. 变量表达式

表达式形式:

${….}

  • 用于获取后台传过来的值

例如:

<p th:text="${userName}"></p>

可以获取基本类型和引用类型

<p th:text="${name}"></p>
<p th:text="${student.id}"></p>
<!--student类的公共属性没有set和get方法,也可以访问到-->
<p th:text="${student.sex}"></p>

Student类有public或private属性有get方法,可以使用$获取信息

  • 获取数据可以通过属性值也可以通过get方法
学校地址:<span th:text=“${student.my school.address}”></span>

<!——  —->
学校地址:<span th:text=“${student.my school.getAddress()}”></span>

2. 选择变量表达式

表达式形式:

*{……}

3. 消息表达式(国际化)

表达式形式:

#{……}

  • 用来获取资源文件中的数据
  • 根据地区的不同来获取不同的语言表达内容

消息表达式国际化

4. 链接网址表达式

表达式形式:

@{……}

  • 用于替换网页中的src,href等的值
  • 处理web应用中的url地址,可以是相对地址也可以是绝对地址
  • @{/}:相对整个应用的根路径

例如:

<script type="text/javascript" th:href="@{/css/home.css}"></script>

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

链接中传参数

使用的是get方式传参

/user/list?id=001

/user/list?id=001&name=张三

1)在@{……}表达式末尾使用()设置参数

<a th:href="@{/user/list(id=001)}"></a>
<!--多个参数-->
<a th:href="@{/user/list(id=001,name='张三')}"></a>

<!--动态传参-->
<a th:href="@{/user/list(id=001,name=${myname})}"></a>

5. 片段表达式

表达式形式:

~{……}

  • 用于引用公共的目标片段
<div th:insert="~{footercopy}"></div>

第三部分 标准表达式

1. 文本

文本文字只是在单引号之间指定的字符串。它们可以包含任何字符,如果字符之中没有空格,可以不加单引号。使用“+”连接文本,也可以使用“|

<p th:text="'hello thymeleaf'"></p>
<p th:text="'学习'+${info}"></p>
<p th:text="|欢迎使用 ${info}|"></p>
<p th:text="你好+|${n1},${s2}|"></p>

2. 数字

数字文字就是:数字,还包括算术运算:+,-,*,/和%,表达式中的值可以进行比较:<,>等等

html实体符号
& gt;>
lt<
ge>=
le<=
not!
eq==
neq!=
  • 遇到字符串的拼接后面都是字符串了
  • 如果出现括号()优先级高,先运算
<p th:text="6+6+'后面是字符了'+10+10"></p>
<!--输出为:12后面是字符了1010 -->
<p th:text="6+6+'后面不是字符了'+(10+10)"></p>
<!--输出为:12后面不是字符了20 -->

3. 布尔

<th:if="布尔值">,布尔值为true显示标签,反之不显示 
<th:if="true|false">标签体</th:if>
<p th:if="${age} &lt; 18">没有成年</p>
<p th:if="${married} and ${age} &gt; 18">使用and</p>

4. null 和 “ ”

null字面量,在页面直接使用,也可以判断数据是否为null。当数据为null时,标签和内容不显示。“”null处理结果一样。

model.addAttribute("name",null);
model.addAttribute("myname","");
<p th:text="null">这是null</p>	//不显示
<p th:text="''">这是""</p>		//不显示
<p th:text="${name}">后台值为null</p>	//不显示
<p th:text="${myname}">后台值为""</p>	//不显示

5. 比较/逻辑运算符

结合布尔使用

and(与)or(或)!(非)not(非)
<p th:if="${age} &lt; 18">没有成年</p>
<p th:if="${age} > 18">成年了</p>

6. 三元运算符

Thymeleaf中的三元运算与Java以及JavaScript中基本一致,如A>B?X:Y,在XY中可以继续嵌套,只是thymeleaf中需要使用括号包含起来,否则报错。

  • A>B?X:Y 省略了Y,如果X>Y为false,整个表达式为null,标签不显示。
<p th:text="0&gt;5 ? '10大于5': '10不大于5'">判断数字大小</p>

<p th:text="${age}!=null ? (${age}&gt;30 ? '大于30': '不大于30'): 'age为null'">嵌套判断</p>

<p th:text="${islogin}?'没有登陆'">登录用户</p>	//不显示

第四部分 设置属性值

属性作用
th:text计算其值表达式并将结果设置为标签的标签体
th:utextth:text会对结果中的特殊字符转义,而th:utext不会
th:attr为标签中任意属性设值,可以一次设置多个属性
th:*为html指定的属性设值,一次设置一个;如th:value,th:type
<input th:type="text" th:value="name"/>

在这里插入图片描述在这里插入图片描述

1. 设置任意属性值 th:attr

th:attr提供了更改标签属性值的能力。th:attr使用比较少,因为其使用比较难,语法不优雅。对于标签的特定属性,请使用th:value,th:action,th:href,th:class,th:src,th:onclick等等。

<form action="/hello.html" method="post" th:attr="action=${myaction}">
    账号:<input type="text" name="username"><br/>
    密码:<input type="password" name="pwd"><br/>
    <input type="submit" value="登录" th:attr="value=${mytext}">
</form>
  • 设置多个属性
<input type="submit" value="登录" th:attr="value=${mytext},οnclick='fun1()'">

不运行模板时:

在这里插入图片描述
运行模板之后,将值进行替换:
在这里插入图片描述

2. 同时设置多个值

th:alt-title:设置alt,title两个属性

th:lang-xmllang:设置lang,xml:lang

<img th:src="@{/image/im1.jpg}" th:alt-title="我的图片" />

<img src="@{/image/im1.jpg}" alt="我的图片" title="我的图片" />

<head th:lang-xmllang="en"></head>

<head xml:lang="en" lang="en"></head>

html标签中lang属性及xml:lang属性的作用

3. boolean属性

HTML具有布尔属性的概念,例如 readonly,还有checkbox的“checked”,这个属性不赋值,默认改值为“true”。也可以使用属性名本身表示true,即checked=“checked”。

AttrController.java

model.addAttribute("selected",true);
model.addAttribute("unselected",false);

attr.html

<input type="checkbox" value="游泳" th:checked="${selected}">游泳<br/>
<input type="checkbox" value="骑行" th:checked="${unselected}">骑行<br/>

4. 设置标签体文本

th:text :用来计算表达式并将结果设置标签体,会对计算结果中特殊字符进行转义。

th:utext:用来计算表达式并将结果设置标签体,不会进行转义。

Controller.java

model.addAttribute("msg","学习的开发语言<b>java</b>等等");
model.addAttribute("xontent","全栈开发<b>vue</b>,<b>java</b>,<b>mysql</b>");

body.html

<p th:text="${msg}">text</p>
<p th:utext="${content}">text</p>

在这里插入图片描述

5. 循环th:each

th:each处理循环,类似jstl中的<c:foreach>

特点:

  1. 循环的对象如果是null,不存在则不循环;
  2. 循环包含自身和标签内全部内容;
  3. 可以遍历的对象:
    • 数组
    • 任何实现java.util.lterable接口的对象
    • Enumeration枚举
    • Map接口对象

语法格式:

<tr th:each="成员遍历:${表达式}">
	<td th:text="${成员}"></td>
</tr>

Controller.java

List<Student> students=new ArrayList<>();
list.add(new Student(1001,"ksda",18));
list.add(new Student(1002,"sdfas",18));
list.add(new Student(1003,"terw",18));
list.add(new Student(1004,"dfgs",18));
model.addAttribute("students",list);

html

<table>
    <tr>
        <th>id</th>
        <th>姓名</th>
        <th>年龄</th>
    </tr>
    <tr th:each="stu:${students}">
        <td th:text="${stu.id}"></td>
        <td th:text="${stu.name}"></td>
        <td th:text="${stu.age}"></td>
    </tr>
</table>

使用th:each时,Thymeleaf提供了一种用于跟踪迭代状态的机制:状态变量。状态变量在每个th:each属性中定义,并包含以下数据:

  1. index 属性:当前迭代索引,从0开始;
  2. count 属性:当前的迭代计数,从1开始;
  3. size 属性:迭代变量中元素的总量;
  4. current 属性:每次迭代的iter变量,即当前遍历到的元素;
  5. even/odd 布尔属性:当前的迭代是偶数还是奇数;
  6. first 布尔属性:当前的迭代是否是第一个迭代
  7. last 布尔属性:当前的迭代是否是最后一个迭代。

循环一个Map

Map<String,String> map=new HashMap<>();
map.put("id","学号");
map.put("name","学生姓名");
map.put("age","年龄");
map.put("classname","所在班级");
model.addAttribute("stumap",map);

html

<p th:each="m:${stumap}">
    <span th:text="${m.key}"></span>
    <span th:text="${m.value}"></span>
</p>

HashMap散列图、Hashtable散列表是按“有利于随机查找的散列(hash)的顺序”。并非按输入顺序。遍历时只能全部输出,而没有顺序

循环list-map

List<Map<String,Student>> listmap=new ArrayList<>();
Map<String,Student> map=new HashMap<>();
map1.put("stu1",s1);
map1.put("stu2",s2);
map1.put("stu3",s3);
listmap.add(map1);

Map<String,Student> map=new HashMap<>();
//创建s4,s5,s6对象
map2.put("stu4",s4);
map2.put("stu5",s5);
map2.put("stu3",s6);
listmap.add(map2);
model.addAttribute("listmap",listmap;

双重循环获取属性及属性值

html

<ul th:each="lm:${listmap}">
    <li th:each="entry:${lm}" th:key="${entry.key}"></li>
    <li th:each="entry:${lm}" th:key="${entry.value}"></li>
</ul>

在这里插入图片描述

6. 判断th:if和th:unless

th:if

th:if:当条件满足时,显示代码片段。条件常用boolean表示,true满足,反之不满足。

thymeleaf中,true不是唯一满足条件。

1)如果表达式结果为布尔值,则为true或者false;

2)如果表达式的值为null,th:if将判定此表达式为false;

3)如果值是数字,为0时,判断为false;不为0时,判定为true;

4)如果值是String,值为“false”,“off”,“no”时,判定为false,否则为true,字符串为空时,也判断为true

5)如果值不是布尔值,数字,字符或字符串的其他对象,只要不为null,则判断为true。

th:unless

th:unless是不满足条件显示代码片段,类似Java中if的else部分。

7. 模板使用

模板就是公用资源,可以多次重复使用的内容。经常把页眉,页脚,菜单做成模板,在各个其他页面也使用。

模板的使用,先定义再使用。可以在当前页面定义模板,也可在其他页面中定义模板。

1)定义模板语法:

<div th:fragment="模板名称">
    模板内容
</div>

2)引用模板(常用insertreplace

  1. 把模板插入到当前位置(在div里面将模板插入)
<div th:insert="模板所在文件名称::模板名称">
    其他内容
</div>
  1. 把模板替换到当前标签内容(替换div为模板)
<div th:replace="模板所在文件名称::模板名称">
    其他内容
</div>
  1. 模板内容(不包含标签)添加到当前标签
<div th:include="模板所在文件名称::模板名称">
    其他内容
</div>

使用id引用模板

<p id="tplid">
    这是模板
</p>
<div th:insert="::#tplid">

</div>

3)模板引用语法

  1. 模板所在文件名称::模板名称
  2. ~{模板所在文件名称::模板名称}
  3. 当前页面:::模板名称 ~{::course}

4)模板作为函数形式使用

<div th:fragment="funtpl(one,two)">
    <p th:text="'hello'+ ${one} + '-' + ${two}"></p>
</div>

th:insert,th:replace使用funtpl模板,可以传入值。

<div th:replace="frag/footer::funtpl(one='张三',two='李四')">
    参数模板
</div>

5)删除模板

th:remove="删除范围值"

  1. all:删除包含标签及其所有子项;
  2. body:不删除包含标签,但删除所有的子项;
  3. tag:删除包含标签,不删除其子项;
  4. all-but-first:删除第一个子项以外的其他所有子项;
  5. none:什么都不删除。该值对于动态计算有用。null也会被视为none。

动态指定模板名称

定义模板

<div th:fragment="menu">
    <b>首页|开发语言|开发工具|咨询</b>
</div>

使用模板

@GetMapping("/tpl")
public String doTemplate(Model model){
    model.addAttribute("tplname","menu");
    return "frag/main";
}
<p>使用model中的数据表示模板名称</p>
<div th:insert="frag/footer::${tplname}"></div>
<br/>

8. th:inline 使用

灵活,使用更方便。

需要将thymeleaf表达式写到标签体中,而不是标签内,可以使用

1)内联语法

[[]][()]内联表达式,任何在th:textth:utext属性中使用的表达式都可以出现在[[]][()]中使用。

[[]]:等价于th:text

[()]:等价于th:utext

2)禁用内联

内容

;里面的内容原样输出。

3)使用JavaScript内联

<script th:inline="javascript">
    var msg = [[${message}]];
    if(msg){
        window.onload=function(){
            alert(msg);
        }
    }
</script>

9. th:with 局部变量

th:with="变量名1=值1,变量名2=值2",定义的变量只在当前标签内有效。

@GetMapping("/var")
public String doVar(Model model){
    model.addAttribute("age",20);
    return "var";
}

var.html

<!--单个变量-->
<div th:with="name='zhangsan'">
    <p th:text="${name}"/>
</div>

<!--多个变量-->
<div th:with="id=1001,name='zhangsan',myage=${age}">
    <p th:text="${id}"/>
    <p th:text="${name}"/>
    <p th:text="${myage}"/>
</div>

10. 工具类对象

官网地址

1)#{execInfo}:模板信息

  • ${#execInfo.templateName}:模板名称
  • ${#execInfo.templateMode}:模板的处理方式

2)#uris:处理url/uri编码解码

  • ${#uris.escapePath(uri)}:编码
  • ${#uris.escapePath(uri,encoding)}:指定编码转码
  • ${#uris.UnescapePath(uri)}:解码
  • ${#uris.unescapePath(uri,encoding)}:指定编码解码

3)#dates:java.util.Date对象的实用程序方法,可以操作数组,set,list。

常用方法:

${#dates.format(date, 'dd/MMM/yyyy HH:mm')}
${#dates.arrayFormat(datesArray, 'dd/MMM/yyyy HH:mm')}
${#dates.listFormat(datesList, 'dd/MMM/yyyy HH:mm')}
${#dates.setFormat(datesSet, 'dd/MMM/yyyy HH:mm')}

4)#numbers:数字对象的实用程序方法

  • ${#numbers.formatInteger(num,size)}:num表示被格式的数字,size表示整数位最少保留几位。

5)#stringsString工具类,就是字符串工具类

  • ${#strings.toUpperCase(name)} :大写
  • ${#strings.toLowerCase(name)} :小写
  • ${#strings.arrayJoin(namesArray,',')} :连接,合并
  • ${#strings.arraySplit(namesStr,',')} :分隔
  • ${#strings.indexof(name,frag)} :查找
    • ${#strings.indexof(name,‘san’)}
  • ${#strings.substring(name,3,5)} :取子串
  • ${#strings.contains(name,'ez')} :是否有字串
  • ${#strings.isEmpty(name)} :判断是否为空

6)#ids#aggregates#maps#sets#lists#arrays#bools#objects等等工具类

@GetMapping("/tools")
public String doVar(Model model){
    model.addAttribute("mydate",new Date());
    model.addAttribute("price",89.35);
    model.addAttribute("myname","zhangsan");
    return "tools";
}

tools.html

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

11. 内部对象

在这里插入图片描述

#request,就是javax.servlet.http.HttpServletRequest

contextPath:[[${#request.getContextPath()}]]

获取请求参数:[[${#request.getParameter('name')}]]

getAttribute:[[${#request.getAttribute('attrName')}]]

#session,直接访问与当前请求关联的javax.servlet.http.HttpSession对象

getAttribute:[[${#session.getAttribute('sessionAttr')}]]

getId:[[${#session.getId()}]]

#servletContext:直接访问与当前请求关联的javax.servlet.ServletContext对象

  • [[${#servletContext.getAttribute('contextAttr')}]]

  • 获取服务器信息:[[${#servletContext.getServerInfo()}]]

    快捷对象

thymeleaf在web环境中,有一系列的快捷方式用于访问请求参数、会话属性等应用属性。

param:用于检索请求参数。 p a r a m . f o o 是一个使用 f o o 请求参数的值 S t r i n g [ ] ,所以 {param.foo}是一个使用foo请求参数的值String[],所以 param.foo是一个使用foo请求参数的值String[],所以{param.foo[0]}将会通常用于获取第一个值。

例:http://localhost:8080/myweb/hello.jsp?foo=lisi&foo=zhangsan&name=dsfd&userid=1001

foo是一个数组。

param获取参数:[[${param.foo[0]}]]

param获取参数:[[${param.foo[1]}]]

参数数量:[[${param.size()}]]

是否有指定参数:[[${param.containsKey('name')}]]

获取参数值:[[${param.userid}]]

session:用于获取session属性。与param同理,只是作用域不同。

作用域的值:[[${session.sessionAttr}]]

session中key的数量:[[${session.size()}]]

application:用于获取应用程序或servlet上下文属性。与param同理。

获取ServletContext作用域的值:[[${application.contextAttr}]]

application中key的数量:[[${application.size()}]]

使用springboot会向全局作用域中添加容器信息,实际上比自己定义的key的数量还多。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值