Thymeleaf简介

    Thymeleaf是一个流行的模板引擎,该模板引擎采用Java语言开发,模板引擎是一个技术名词,是跨领域跨平台的概念,在Java语言体系下有模板引擎,在C#、PHP语言体系下也有模板引擎。除了thymeleaf之外还有Velocity、FreeMarker等模板引擎,功能类似。

    Thymeleaf的主要目标在于提供一种可被浏览器正确显示的、格式良好的模板创建方式,因此也可以用作静态建模。你可以使用它创建经过验证的XML与HTML模板。使用thymeleaf创建的html模板可以在浏览器里面直接打开(展示静态数据),这有利于前后端分离。需要注意的是thymeleaf不是spring旗下的。这里我们使用thymeleaf 3版本。

    thymeleaf官方网址:https://www.thymeleaf.org/

    thymeleaf官方在线文档网址:https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html

    

    第一个thymeleaf程序

    1、要想使用thymeleaf,首先需要添加thymeleaf依赖,这里与之前不一样的是我们需要勾选thymeleaf模板引擎依赖,其他的几个依赖我们之前已经说过,这里就不再进行讲解了。

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-thymeleaf</artifactId>
  4. </dependency>

    

    2、修改spring boot配置文件添加如下代码,在开发阶段建议关闭thymeleaf缓存,因为我们需要对开发项目进行实时修改,所以在这里我们先将缓存关闭。

  1. #关闭thymeleaf缓存
    spring.thymeleaf.cache=false

    3、thymeleaf会对html中的标签进行严格的校验,如果标签缺少结束的话thymeleaf会报错,比如之前我们在html中写的<input>标签,如果缺少</input>则会报错。类似于这种错误不容易发现所以我们可以通过下面的方式去除thymeleaf的严格校验,首先添加依赖(需要手动添加,无法自动生成):

  1. <dependency>
  2. <groupId>net.sourceforge.nekohtml</groupId>
  3. <artifactId>nekohtml</artifactId>
  4. <version>1.9.22</version>
  5. </dependency>

    pom.xml中添加完依赖之后,在spring boot配置文件中添加如下内容(完成以上两步之后就可以关闭thymeleaf的严格校验了):

  1. spring.thymeleaf.mode=LEGANCYHTML5

    4、创建controller,通过Model向html中传递数据,这里我们需要跳转html,不需要转换Json数据所以不需要使用RestController,Controller即可。thymeleaf默认的视图解析器为html,所以controller跳转时不需要再加html后缀,直接写"index"。

  1. package com.scm.thymeleaf.controller;
  2.  
  3. import org.springframework.stereotype.Controller;
  4. import org.springframework.ui.Model;
  5. import org.springframework.web.bind.annotation.RequestMapping;
  6.  
  7. @Controller
  8. public class ThymeleafController {
  9. @RequestMapping("/firstThymeleaf")
  10. public String thymeleafTest(Model model){
  11. model.addAttribute("info","This is my first thymeleaf!");
  12. return "index";
  13. }
  14. }

    5、在resources/templates里面创建一个index.html,填写下面内容。

     注意:这里我们使用了thymeleaf,所以我们在<html>标签中添加 xmlns:th="http://www.thymeleaf.org"

  1. <!DOCTYPE html>
  2. <html xmlns:th="http://www.thymeleaf.org">
  3. <head>
  4. <meta charset="UTF-8"/>
  5. <title>Spring boot集成 Thymeleaf</title>
  6. </head>
  7. <body>
  8. <p th:text="${info}">Spring boot集成 Thymeleaf</p>
  9. </body>
  10. </html>

    在html中我们通过th:text属性接收controller的"info"参数。并且将动态数据替换掉静态数据"Spring boot集成 Thymeleaf";

    Springboot使用thymeleaf作为视图展示的时候,我们将模板文件放置在resource/templates目录下,静态资源放置在resource/static目录下。

    

    Thymeleaf表达式

     标准变量表达式

    先创建一个controller用于向html传递数据,这里我们创建了一个User类。

  1. package com.scm.thymeleaf.bean;
  2.  
  3. import lombok.Data;
  4.  
  5. @Data
  6. public class User {
  7. private int id;
  8. private String Name;
  9. private String Phone;
  10. public User(){}
  11. public User(int id,String Name,String Phone){
  12. this.id = id;
  13. this.Name = Name;
  14. this.Phone = Phone;
  15. }
  16. }

     Controller

  1. package com.scm.thymeleaf.controller;
  2.  
  3. import com.scm.thymeleaf.bean.User;
  4. import org.springframework.stereotype.Controller;
  5. import org.springframework.ui.Model;
  6. import org.springframework.web.bind.annotation.RequestMapping;
  7.  
  8. @Controller
  9. public class userInfo {
  10. @RequestMapping("/userInfo")
  11. public String userInfos(Model model){
  12. User user = new User(1000,"scm","188888888");
  13. model.addAttribute("u",user);
  14. model.addAttribute("hello","Hello World");
  15. return "user";
  16. }
  17. }

    user.html

    html中我们接收了controller中传递的User对象,html中的${对象名.属性},对象名是addAttribute("键",“值”)方法中的键,而不是我们创建的User类。

    在<td></td>标签中我们写入了静态数据,这些静态数据会被动态数据所取代,但是如果我们找到html本地路径,在本地直接打开user.html的话会显示静态资源,而不显示动态资源。

  1. <!DOCTYPE html>
  2. <html xmlns:th="http://www.thymeleaf.org">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8.  
  9. <table>
  10. <tr>
  11. <td th:text="${u.id}">1</td>
  12. <td th:text="${u.name}">a</td>
  13. <td th:text="${u.phone}">137</td>
  14. </tr>
  15. </table>
  16. </body>
  17. </html>

    选择变量表达式

    在标准变量表达式中我们通过${对象名.属性}的方式接收controller传递的参数。如果User类中有几十个属性甚至更多,那么岂不是要写几十次对象名,这样就显得麻烦。而使用选择变量表达式之后我们只需要声明一次对象名就可以了。代码如下:

  1. <table>
    <tr th:object="${u}">
    <td th:text="*{id}">1</td>
    <td th:text="*{name}">a</td>
    <td th:text="*{phone}">137</td>
    </tr>
    </table>

    在<tr></tr>标签中我们声明了一个th:object获取了controller中的User对象,那么在这个<tr>标签中,我们就可以直接用*{属性名}的方式。这样如果User中的属性多的话我们只需要写属性名即可。

    url表达式

    将后台传入的数据拼接到url中,通过url表达式可以动态的拼接url。这里使用th:href属性,前两个为非Restful风格的get请求,后两个为Restful风格请求。

  1. <a href="info.html" th:href="@{/user/info(id=${u.id})}">参数拼接</a>
  2. <a href="info.html" th:href="@{/user/info(id=${u.id},phone=${u.phone})}">多参数拼接</a>
  3. <a href="info.html" th:href="@{/user/info/{uid}(uid=${u.id})}">restful风格</a>
  4. <a href="info.html" th:href="@{/user/info/{uid}/abc(uid=${u.id})}">restful风格</a>   

        

    从图中看出我们将鼠标悬浮在超链接上,在下方我们可以看到动态拼接的url,这些url中的动态数据都是从controller中传递到url中的。

    Thymeleaf运算符和表达式

    重新创建一个controller,先在这里设置一些我们将要用到的参数。  

  1. package com.scm.thymeleaf.controller;
  2.  
  3. import com.scm.thymeleaf.bean.User;
  4. import org.springframework.stereotype.Controller;
  5. import org.springframework.ui.Model;
  6. import org.springframework.web.bind.annotation.RequestMapping;
  7.  
  8. import javax.servlet.http.HttpSession;
  9. import java.util.Date;
  10.  
  11. @Controller
  12. public class userInfo {
  13. @RequestMapping("/userInfo1")
  14. public String userInfos1(Model model, HttpSession seesion){
  15. model.addAttribute("page",5);//字符串拼接
  16. model.addAttribute("sex",1);//三目运算符
  17. seesion.setAttribute("phone","16666666666");//session内置对象
  18. model.addAttribute("myDate",new Date());//#Date类
  19. return "user";
  20. }
  21. }

    字符串拼接(两种方式)

    方式一:这种方式与java中字符串拼接类似。

  1. <span th:text="'当前是第'+${page}+'页 ,共'+${page}+'页'"></span>

    方式二:使用“|”减少了字符串的拼接,在|  |之间thymeleaf可以自动识别 ${}表达式。

  1. <span th:text="|当前是第${page}页,共${page}页|"></span>

    三目运算符

  1. <span th:text="${sex eq 0} ? '男' : '女'">未知</span>

    基本运算和关系判断

  1. 算术运算:+ , - , * , / , %
  2.  
  3. 关系比较: > , < , >= , <= ( gt , lt , ge , le )
  4.  
  5. 相等判断:== , != ( eq , ne )

    thymeleaf内置对象

    模板引擎提供了一组内置的对象,这些内置的对象可以直接在模板中使用,这些对象由#号开始引用。

    1、#request:相当于是HttpServletRequest对象

  1. <span th:text="${#request.getContextPath()}"></span><br>

    2、#session: 相当于是HttpSession对象

  1. <span th:text="${#session.getAttribute('phone')}"></span><br>

    除了上面的对象之外,工作中常使用的数据类型,如集合,时间,数值,thymeleaf的专门提供了功能性对象来处理它们,下面列举一部分。

    1、#dates: java.util.Date对象的实用方法,可以调用里面的方法。#后边都多加一个s,例如#dates就是Date类。myDate参数是在controller创建的一个new Date();

  1. <span th:text="${#dates.format(myDate, 'yyyy-MM-dd HH:mm:ss')}"></span>  

    2、#numbers: 格式化数字对象的实用方法;(Number类)

    3、#strings: 字符串对象的实用方法;(String类)

    4、#objects: 对objects操作的实用方法;(Object类)

    5、#lists: list的实用方法,比如<span th:text="${#lists.size(datas)}">(List类)

    6、#aggregates: 对数组或集合创建聚合的实用方法;(Aggregate类)

    

    Thymeleaf常用属性

     th:each

    该属性较为常用,比如从后台传来一个对象集合那么就可以使用此属性遍历输出,它与JSTL中的<c: forEach>类似,此属性既可以循环遍历集合,也可以循环遍历数组及Map。

    1、循环list集合

    先创建controller构建list数据,这里我们还使用上边的User类。 

  1. package com.scm.thymeleaf.controller;
  2.  
  3. import com.scm.thymeleaf.bean.User;
  4. import org.springframework.stereotype.Controller;
  5. import org.springframework.ui.Model;
  6. import org.springframework.web.bind.annotation.RequestMapping;import java.util.ArrayList;
  7. import java.util.Date;
  8.  
  9. @Controller
  10. public class userInfo {
  11. @RequestMapping("/userInfo2")
  12. public String userInfo3(Model model){
  13. ArrayList al = new ArrayList();
  14. for(int i = 0;i < 10;i++){
  15. User user = new User(i,"scm"+i,"1666666666"+i);
  16. al.add(user);
  17. }
  18. model.addAttribute("list",al);
  19. return "user";
  20. }
  21. }

    user.html    

  1. <table>
  2. <tr th:each="user, interStat : ${list}">
  3. <td th:text="${interStat.index}"></td>
  4. <td th:text="${user.id}"></td>
  5. <td th:text="${user.name}"></td>
  6. <td th:text="${user.phone}"></td>
  7. </tr>
  8. </table>

    让我们来分析一下html中的代码。首先我们通过${list}接收到了controller传递的ArrayList集合。那么引号中的user和interStat又分别是什么呢?其实这两个都是我们其的一个别名,在list集合中存入了User对象,注意不要将html中的user和User对象混淆,html中的user是可以随意命名的,比如这里我们可以把html中的user换成u,那么在td中的${}我们就要改为u.id、u.name和u.phone。通俗的讲我们就是把集合中的对象起了一个别名,然后通过别名去遍历获取集合中的值。interStat同样是我们起的一个别名,这里的interStat类似于jstl里面foreach的varStatus,可以获取到当前的迭代信息。

    这里有另一种写法就是将interStat省略,这样thymeleaf会自动为我们起一个名字,命名规则为对象别名+Stat。本例我们对象别名为user,所以当我们省略interStat时,thymeleaf为我们自动起一个userStat的名字,然后通过userStat.index可以达到同样的效果。再比如我们将别名改为u,这时自动生成的就是uStat。如下的代码与上边的代码是等效的。

  1. <tr th:each="user:${list}">
  2. <td th:text="${userStat.index}"></td>
  3. <td th:text="${user.id}"></td>
  4. <td th:text="${user.name}"></td>
  5. <td th:text="${user.phone}"></td>
  6. </tr>

    总结两种写法,第一种写法我们手动起了两个别名,一个用于调用对象属性,另一个用于查看迭代信息。第二种写法只需要我们起一个别名,另外一个别名是thymeleaf根据我们起的对象别名自动生成的。下面是interStat里面一些属性的含义:

  1. index: 当前迭代对象的index(从0开始计算)
  2. count: 当前迭代对象的个数(从1开始计算)
  3. size: 被迭代对象的大小
  4. current: 当前迭代变量
  5. even/odd: 布尔值,当前循环是否是偶数/奇数(从0开始计算)
  6. first: 布尔值,当前循环是否是第一个
  7. last: 布尔值,当前循环是否是最后一个

    

    2、遍历map集合

    controller构建map数据

  1. @RequestMapping("/userInfo3")
  2. public String userInfo3(Model model){
  3.  
  4. HashMap<String, User> userMap = new HashMap<>();
  5. for (int i = 0; i < 10; i++) {
  6. User user = new User();
  7. user.setId(i);
  8. user.setName("scm" + i);
  9. user.setPhone("13"+i+"11111111");
  10. userMap.put(String.valueOf(i), user);
  11. }
  12. model.addAttribute("userMap", userMap);
  13. return "user";
  14. }

    html,myMapVal.key相当于map的键,myMapVal.value相当于map中的值。   

  1. <div th:each="myMapVal : ${userMap}">
  2. <span th:text="${myMapValStat.count}"></span>
  3. <span th:text="${myMapVal.key}"></span>
  4. <span th:text="${myMapVal.value.name}"></span>
  5. <span th:text="${myMapVal.value.phone}"></span>
  6. <br/>
  7. </div>

    遍历map与遍历list集合原理类似,只不过map是以键值对的形式存在的,所以我们需要通过别名.key方式获取键,别名.value获取值。

    

    3、遍历循环数组

    controller构建数组数据

  1. @RequestMapping(value="/usersArray")
  2. public String selectAllUserArray (Model model) {
  3. User[] userArray = new User[10];
  4. for (int i = 0; i < 10; i++) {
  5. User user = new User();
  6. user.setId(i);
  7. user.setName("scm" + i);
  8. user.setPhone("13"+i+"11111111");
  9. userArray[i] = user;
  10. }
  11. model.addAttribute("userArray", userArray);
  12. return "user";
  13. }

    user.html

  1. <div th:each="myArrayVal : ${userArray}">
  2. <div th:text="${myArrayVal.id}"></div>
  3. <div th:text="${myArrayVal.name}"></div>
  4. <div th:text="${myArrayVal.phone}"></div>
  5. </div>

    th:id

    动态设置html标签中的id属性,比如:我们从后台传入一个字符串hello,那么就可以将${hello)的值作为span标签的id。   

  1. <span th:id="${hello}">good</span>

    th:if

    条件判断,比如后台传来一个变量,判断该变量的值,0为男,1为女: 

  1. <span th:if="${sex} == 0" >
  2. 男:<input type="radio" name="sex" th:value="男" />
  3. </span>
  4. <span th:if="${sex} == 1">
  5. 女:<input type="radio" name="sex" th:value="女" />
  6. </span>

    th:switch/th:case

    switch,case判断语句,比如:  

  1. <div th:switch="${sex}">
  2. <p th:case="0">性别:男</p>
  3. <p th:case="1">性别:女</p>
  4. <p th:case="*">性别:未知</p>
  5. </div>

    这里的*表示默认,当上面的case都是false的时候,会执行默认的内容。

    th:value

    类似html标签中的value属性,能对某元素的value属性进行赋值,比如: 

  1. <input type="hidden" id="userId" name="userId" th:value="${userId}">

    th:inline

    th:inline 有三个取值类型

    • text(从后台取出数据展示)   
  1. <span th:inline="text">Hello, [[${name}]]</span>
  2. 等同于:
  3. <span>Hello, <span th:text="${name}"></span></span>

    类似于第二行代码中的例子。我们需要在第一个span中的Hello,后动态获取数据,这时需要再写一个span标签然后使用th:text属性。但是我们可以使用th:inline="text"直接实现等同的效果。

    • none(有时候希望在html中直接显示[[1, 2, 3], [4, 5]],此时可以使用none)

    在th:inline="text"中使用[[${ }]]的方式获取controller的数据。那么当我们想直接输出[[1,2,3]]这样的字符串类型的怎么办呢。如果我们直接<div>[[1,2,3]]</div>发现会报错,因为thymeleaf自动将[[ ]]识别为获取传递的数据。这时就要用到th:linline="none"了。

  1. <p th:inline="none"> [[1, 2, 3], [4, 5]]!</p>

    使用none之后就相当于告诉thymeleaf这个双中括号内的内容不是传递的参数,你不需要去识别。这样thymeleaf就会知道了。

    • javascript(如果希望在JavaScript中获取后台相应的数据,可以使用下面内容:)

    创建controller构建数据  

  1. @RequestMapping("/userInfo4")
  2. public String userInfo4(Model model){
  3. model.addAttribute("name","scm");
  4. return "javascript";
  5. }

    javascript.html 

  1. <!DOCTYPE html>
  2. <html xmlns:th="http://www.thymeleaf.org">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8.  
  9. </body>
  10. <script th:inline="javascript" type="text/javascript">
  11. var msg = "Hello," + [[${name}]];
  12. alert(msg);
  13. </script>
  14. </html>

    可以看到在th:inline="javascript"可以让我们在javascript中获取controller传递的数据,同样是[[${ }]]的格式接收数据。

    

    到这里为止thymeleaf的第一个程序和thymeleaf相关的常用表达式和相关属性就讲完了,一些不太常用的这里就不做讲解了。如果发现错误或有疑问的地方请及时评论,谢谢。

    

Spring全家桶之spring boot(五)的更多相关文章

  1. Spring全家桶之spring boot(三)

    spring boot集成mybatis 众所周知,spring与springmvc可以无缝集成,而mybatis不是spring旗下的框架,因此需要进行配置,当然,这里的配置也是非常简单的. 1.首 ...

  2. Spring全家桶之spring boot(二)

    spring boot的两种配置文件: 虽然spring boot可以帮助我们进行一些配置项,但是有些内容还是需要开发者自己进行配置,因此spring boot提供了配置文件以供开发者配置.sprin ...

  3. Spring全家桶之spring boot(一)

    spring boot框架抛弃了繁琐的xml配置过程,采用大量的默认配置简化我们的开发过程.使用spring boot之后就不用像以前使用ssm的时候添加那么多配置文件了,spring boot除了支 ...

  4. Spring全家桶之spring boot(四)

    spring boot拦截器.过滤器.servlet和健康检查机制  spring boot拦截器 spring boot配置拦截器与原来大致相同,只是需要在拦截器的配置类上添加@Configurat ...

  5. 10分钟详解Spring全家桶7大知识点

    Spring框架自2002年诞生以来一直备受开发者青睐,它包括SpringMVC.SpringBoot.Spring Cloud.Spring Cloud Dataflow等解决方案.有人亲切的称之为 ...

  6. Java秋招面试复习大纲(二):Spring全家桶+MyBatis+MongDB+微服务

    前言 对于那些想面试高级 Java 岗位的同学来说,除了算法属于比较「天方夜谭」的题目外,剩下针对实际工作的题目就属于真正的本事了,热门技术的细节和难点成为了面试时主要考察的内容. 这里说「天方夜谭」 ...

  7. 一文解读Spring全家桶 (转)

    Spring框架自2002年诞生以来一直备受开发者青睐,它包括SpringMVC.SpringBoot.Spring Cloud.Spring Cloud Dataflow等解决方案.有人亲切的称之为 ...

  8. 【转】Spring全家桶

    Spring框架自诞生以来一直备受开发者青睐,有人亲切的称之为:Spring 全家桶.它包括SpringMVC.SpringBoot.Spring Cloud.Spring Cloud Dataflo ...

  9. Spring全家桶–SpringBoot Rest API

    Spring Boot通过提供开箱即用的默认依赖或者转换来补充Spring REST支持.在Spring Boot中编写RESTful服务与SpringMVC没有什么不同.总而言之,基于Spring ...

随机推荐

  1. ISWC 2018概览:知识图谱与机器学习

    语义网的愿景活跃且良好,广泛应用于行业 语义网的愿景是「对计算机有意义」的数据网络(正如 Tim Berners Lee.James Hendler 和 Ora Lassila 在<科学美国人& ...

  2. vue中解决时间在ios上显示NAN的问题

    最近在用vue,遇到倒计时在ios上显示为NAN的问题. 因为做的是倒计时支付,思路是获取服务器时间和下单时间,再转成秒级时间戳做差值. 在网上找到说是ios 不支持例如2018-09-01 10:0 ...

  3. HTTP 前世今生

    HTTP 协议在我们身边随处可见,只要上网就离不开它.不论是用浏览器还是 App,不论是看新闻.短视频还是听音乐.玩游戏,后面总会有 HTTP 在默默为你服务. Http 协议是怎么来的?最开始是什么 ...

  4. tensor求和( tensor.sum())

    1. torch.sum(input, dim, out=None) 参数说明: input:输入的tensor矩阵. dim:求和的方向.若input为2维tensor矩阵,dim=0,对列求和:d ...

  5. 安装和使用redis

    我现在只是在window上使用redis在其他平台上暂时没有操作过,如果你有其他好的意见欢迎提出来! 安装redis具体可查看:http://www.runoob.com/redis/redis-in ...

  6. 基于jenkins自动打包并部署docker环境

    一.实验环境 git                      192.168.200.71 jenkins    192.168.200.72 docker               192.16 ...

  7. Mozilla开始推送Firefox Preview 5.0版 支持画中画特性

    Mozilla 发布了 5.0 版本的 Firefox Preview 浏览器,根据 GitHub 上的发布说明,这次更新带来了一系列新的改进.其中包含对五个新的附加组件的支持,引入了对 Progre ...

  8. Native Boot 从一个 VHD 引导系统的相关说明

    Native Boot 是 Windows 7 和 Windows Server 2008 R2 提供的一个新的功能,它允许从一个 VHD 文件引导一个操作系统,但是需要注意的是目前的 Windows ...

  9. html入门详细笔记

    Web的基本概念 什么是Web? 中文翻译"网页",它是一些列技术的总称,(包括网站的前台布局.后台程序.美工.数据库开发等),我们称它为网页. Web标准 结构标准(HTML) ...

  10. 解决Visual Studio (VS) 插件下载缓慢

    1.关闭IPV6协议 因为如果都支持IPV6协议,会自动使用IPV6下载扩展. 因为IPV6还没有建立完善,所以可能会比较慢. 百度经验:怎样关闭IPV6协议 2.给IPV6添加DNS 百度: 240 ...