SpringTemplate——Thymeleaf入门

一,Thymeleaf介绍

Web动态页面的开发最早是使用JSP技术来开发,随着技术的更替,目前主流的技术方案是Thymeleaf。他是一个非常强大的框架模板,与HTML融合十分密切,也是SPring默认的模板方案。

1.何为模板

我们有如下一个歌曲属性:

{
    "id":"1",
    "name":"成都"
}

我们通过一定手段将参数传入模板,再在模板中接受:

<!DOCTYPE html>
<html lang="en">
    <head>
    </head>
        <body>
            <h1 th:text="${songList.name}"></h1>
        </body>
</html>

之后模版会将其渲染成普通的HTML页面:

<!DOCTYPE html>
<html lang="en">
    <head>
    </head>
        <body>
            <h1>成都</h1>
        </body>
</html>

如上,我们通过模板引擎,可以把Java对象中的数据和模板页面合并,渲染出一个真实的html页面来。如果之后name的名称改变,渲染的页面也会跟着改变。

2.初始化Thymeleaf

  • 添加依赖

首先添加Maven依赖。

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
  • 传递数据

导入依赖之后便可以向模板传递数据。SpringMVC对页面数据层的封装非常完善,因此我们只需要在方法中引入一个model对象,然后调用model的相应方法就能将参数传入到页面中去。

Model的全类名为:

import org.springframework.ui.Model;

我们尝试着传入一个歌单对象:

@Controller
public class SongListControl {

  //此歌单数据和上面的成都对应
  @Autowired
  private SongListService songListService;

  @RequestMapping("/songlist")
  public String index(@RequestParam("id")String id,Model model){

    SongList songList = songListService.get(id);
    //传递歌单对象到模板当中
    //第一个 songList 是模板中使用的变量名
    // 第二个 songList 是当前的对象实例
    model.addAttribute("songList",songList);

    return "songList";
  }
}
  • 模板文件

SpringMVC中对于模板文件是有固定的存放位置的,为工程的src/main/resources/templates目录。

因此,我们写的 return "songList"会自动查找src/main/resources/templates/songList.html文件,后缀名系统会自动匹配,也无需写成return "songList.html"

songList文件格式如下:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <link rel="stylesheet" href="/css/songList.css" />
    <title>歌单</title>
  </head>
  <body>
    <h1 th:text="${songList.name}"></h1>
  </body>
</html>

注意:

  1. 虽然此文件后缀也是html,且大部分内容跟html文件很像,但是因为他放置在src/main/resources/templates目录下,且含有变量th:text="${...}",所以其实他不是html文件,而是Thymeleaf模板。html静态文件放在src/main/resources/static目录下。
  2. xmlns:th="http://www.thymeleaf.org的作用是,在写代码时,让软件识别Thymeleaf语法。
  3. 只要在工程的src/main/resources/templates目录下放置了文件,就表示需要用到Thymeleaf,这些文件就是模板,因此必须在pom.xml中导入依赖。

二,Thymeleaf变量

Thymeleaf 模板语法非常强大,相当于是一门动态编程语言,所以很多语言的特性它都支持,比如说变量、循环、条件等,在我们上节中使用的 th:text="${...}" 就是使用变量技术。

1.模板变量

由于 Thymeleaf 是完全兼容 HTML 的,所以为了不破坏 HTML 结构,Thymeleaf 采用了自定义 HTML 属性的方式来生成动态内容。

th:text 这个属性就是 Thymeleaf 自定义的 HTML 标签属性,th为Thymeleaf缩写,作用就是替换掉html标签的内部内容。例如:

<span th:text="${hello}">HelloWorld</span>

这段代码的含义就是用hello的参数值替换span标签中的内容。加入标签里面的内容是萨瓦迪卡,那么这句话的渲染结果就是:

<span>萨瓦迪卡</span>

${hello}即为读取变量。如果我们想要获得变量,就需要先将变量设置到模板上下文中去,即在Controller中使用model.addAttribute("hello","萨瓦迪卡")方法来设置变量。

第一个参数设置的就是上下文变量名(变量名是可以随便定义),第二参数设置的是变量值(可以是任意的对象)。

2.对象变量

模板语言还可以支持对象的输出,我们可以调用参数的属性,像我们需要的内容调用出来。

我们给songList添加一些内容:

import org.springframework.ui.Model;

@Controller
public class DemoControl {

  @RequestMapping("/demo")
  public String index(Model model){
    
    SongList songList = new SongList();
    songList.setId("0001");
    songList.setName("爱你一万年");

    model.addAttribute("sl",songList);
    return "demo";
  }
}

之后便可以在模板中通过th:text="sl.name"th:text="sl.id"分别获取到name和id的值。

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
  <head>
    <meta charset="UTF-8" />
  </head>
  <body>
    <span th:text="${sl.id}"></span>
    <span th:text="${sl.name}"></span>
  </body>
</html>

注:对象只要是POJO类,即可通过该方法调用对象中的对象,和Java语法类似。

三,Thymeleaf循环语句

1.遍历打印元素属性

和Java相似,Thymeleaf也可以实现标签属性的循环,th:each代表的就是循环语句。

<ul th:each="song : ${songs}">
  <li th:text="${song.name}">歌曲名称</li>
</ul>
  • ${songs}是从模版上下文中获取的变量;
  • song是songs变量遍历后的每一个对象;
  • ${song.name}就可以获取遍历中的歌曲名称了。

我们继续添加对象内容:

 @RequestMapping("/demo")
  public String index(Model model){
    List<Song> songs = new ArrayList<>();

    Song song = new Song();
    song.setId("0001");
    song.setName("朋友");
    songs.add(song);

    song = new Song();
    song.setId("0002");
    song.setName("夜空中最亮的星");
    songs.add(song);

    model.addAttribute("songs",songs);
    return "demo";
  }

通过上面的语句便可以将两个名字循环打印在页面中。

Thymeleaf 支持各种数据类型,如 List ,还可以支持数组、Map,你可以当成 Java 的 for 语句一样,集合类都可以支持

2.打印表的索引值

我们经常看到有些列表需要显示当前行数,这个时候,就需要借助 th:each语句的另一种写法:

<ul th:each="song,it: ${songs}">
  <li>
    <span th:text="${it.count}"></span>
    <span th:text="${song.name}"></span>
  </li>
</ul>

运行后结果如下:

  • 1朋友
  • 2夜空中最亮的星

这段代码中多了一个it参数,如果定义了就可以通过这个it对象来获取更多的统计需求,具体参数如下:

  • it.index
    

    当前迭代对象的 index(从 0 开始计算),如果想从 0 开始显示行数用这个就可以了

  • it.count
    

    当前迭代对象的 index(从 1 开始计算),如果显示行数用这个就可以了

  • it.size
    

    被迭代对象的大小,如果想获取列表长度,用这个就可以了

  • it.current
    

    当前迭代变量,等同与上面的 song

  • it.even/odd
    

    布尔值,当前循环是否是偶数/奇数(从 0 开始计算)

  • it.first
    

    布尔值,当前循环是否是第一个

  • it.last
    

    布尔值,当前循环是否是最后一个

模板中的布尔值需要结合条件语句来处理的

上面我们显示的都是单层的循环,如果你的数据对象是有多级的,也可以嵌套循环。

四,Thymeleaf表达式

Thymeleaf表达式主要有两种场景:

  • 字符串处理
  • 数据转化

1.字符串处理

类似于视频的计时显示00:00/45:00,大家应该很容易明白这个代表的就是这个视频从 0 分 0 秒开始,总共 45 分钟。在 Thymeleaf 中这种显示就需要借助+完成字符拼接:

<span th:text="'00:00/'+${totalTime}"></span>

注意需要使用’ ‘包裹住字符00:00/否则会报错

字符串拼接优化

可以使用||包裹代码,这样就可以避免使用’…‘+’…’

<span th:text="|00:00/${totalTime}|"></span>

2.数据转化

Thymeleaf 默认集成了大量的工具类可以方便的进行数据转化,一般我们使用最多的是dates。

如果想要处理LocalDateLocalDateTime类,可以在pom.xml中添加如下依赖:

<dependency>
  <groupId>org.thymeleaf.extras</groupId>
  <artifactId>thymeleaf-extras-java8time</artifactId>
  <version>3.0.4.RELEASE</version>
</dependency>

该库会自动添加一个temporals工具类。

工具类的运用和变量不同,变量的使用是${变量名},工具类的使用是#{工具类}。具体运用如下:

dates/temporals

二者支持的方式是一样的,只是支持的类型不同,dates支持的是Date类,temporals支持的是LocalDate和LocalDateTime类。

java.util.Date 类和 LocalDateTime 类功能是一样的,不同的是 LocalDateTime 是 Java8 才出现的,一些老的应用还是用 Date 类的。

我们一般使用dates/temporals用于处理日期类型到字符串的转化,比如显示年月日:

<p th:text="${#dates.format(dateVar, 'yyyy-MM-dd')}"></p>
<p th:text="${#dates.format(dateVar, 'yyyy年MM月dd日')}"></p>

或者年月日时分秒:

<p th:text="${#dates.format(dateVar, 'yyyy-MM-dd HH:mm:ss')}"></p>
<p th:text="${#dates.format(dateVar, 'yyyy年MM月dd日 HH时mm分ss秒')}"></p>

java代码如下:

 @RequestMapping("/demo")
  public String index(Model model){

    Date dateVar = new Date();

    model.addAttribute("dateVar",dateVar);
    return "demo";
  }

如果类型是LocalDate/LocalDateTime那么就把#dates换成#temporals

 @RequestMapping("/demo")
  public String index(Model model){
    LocalDateTime dateVar = LocalDateTime.now();

    model.addAttribute("dateVar",dateVar);
    return "demo";
  }
String

除了日期以外,#string也是使用较多的,支持字符串的数据处理,如:

#strings 也是我们使用比较多的,支持字符串的数据处理,比如

  • ${#strings.toUpperCase(name)}
    

    把字符串改成全大写

  • ${#strings.toLowerCase(name)}
    

    把字符串改成全小写

  • ${#strings.arrayJoin(array,',')}
    

    把字符串数组合并成一个字符串,并以,连接,比如["a","b"]执行后会变成a,b

  • ${#strings.arraySplit(str,',')}
    

    把字符串分隔成一个数组,并以,作为分隔符,比如a,b执行后会变成["a","b"];如果abc没有匹配到,执行后会变成["abc"]

  • ${#strings.trim(str)}
    

    把字符串去空格,左右空格都会去掉

  • ${#strings.length(str)}
    

    得到字符串的长度,也支持获取集合类的长度

  • ${#strings.equals(str1,str2)}
    

    比较两个字符串是否相等

  • ${#strings.equalsIgnoreCase(str1,str2)}
    

    忽略大小写后比较两个字符串是否相等

这些函数可以尝试去练习一下,基本上这些多做一些产品开发就非常熟练了

完整的内置对象,大家了解就可以了,用到的时候自己查查文档。

点此查看使用文档

内联表达式

th:text还有一种更简便的写法,就是将变量写在html里面,如:

<span>Hello [[${msg}]]</span>

只需要在java代码中传入参数:

  @RequestMapping("/demo")
  public String index(Model model){
    String msg = "丫丫";

    model.addAttribute("msg",msg);
    return "demo";
  }

用内联表达式执行日期函数:

<p>[[ ${#dates.format(dateVar, 'yyyy-MM-dd')} ]]</p>
<p>[[${#dates.format(dateVar, 'yyyy年MM月dd日')}]]</p>

<p>[[${#dates.format(dateVar, 'yyyy-MM-dd HH:mm:ss')}]]</p>
<p>[[${#dates.format(dateVar, 'yyyy年MM月dd日 HH时mm分ss秒')}]]</p>

五、Thymeleaf条件语句

语法为th:if,当if表达式的值为true的情况下就会执行渲染

<span th:if="${user.sex == 'male'}"></span>

或者使用th:unless,表示否定条件,和if相反。

<span th:unless="${user.sex == 'male'}"></span>

Java代码如下:

 @RequestMapping("/demo")
  public String index(Model model){
    User user = new User();
    user.setId("0001");
    user.setName("范闲");
    user.setSex("male");
    model.addAttribute("user",user);
    return "demo";
  }

除了boolean值以外,Thymeleaf还认为一下表达式为true:

  • 值非空
  • 值是非零数字
  • 值是字符串,但不是false,off或者no
  • 值不是boolean值,数字,character或者字符串

String逻辑判断

在很多时候,我们还会借助#string这个内置对象来做逻辑判断和数据处理,比如isEmpty检查变量是否为空或null:

${#strings.isEmpty(name)}
//数组
${#strings.arrayIsEmpty(name)}
//集合
${#strings.listIsEmpty(name)}

测试一下:

  @RequestMapping("/demo")
  public String index(Model model){
    String str1 = "a";
    String str2 = "";
    String str3 = "  ";
    String str4 = null;
    model.addAttribute("str1",str1);
    model.addAttribute("str2",str2);
    model.addAttribute("str3",str3);
    model.addAttribute("str4",str4);
    return "demo";
  }

模板代码如下:

<p th:if="${#strings.isEmpty(str1)}">String str1 = "a";</p>
<p th:if="${#strings.isEmpty(str2)}">String str2 = "";</p>
<p th:if="${#strings.isEmpty(str3)}">String str3 = "  ";</p>
<p th:if="${#strings.isEmpty(str4)}">String str4 = null;</p>

运行结果只有String str1 = “a“没有显示出来,其他几种都匹配为true

contains

检查字符串是否包含片段

${#strings.contains(name,'abc')}

除此之外还有其他几种常用的判断:

  • ${#strings.containsIgnoreCase(name,'abc')}
    

    先忽略大小写字母,然后去判断是否包含指定的字符串

  • ${#strings.startsWith(name,'abc')}
    

    判断字符串是不是以 abc 开头的

  • ${#strings.endsWith(name,'abc')}
    

    判断字符串是不是以 abc 结束的

#strings 的字符串操作函数

除了字符串判断语句外,#strings 还支持字符串的数据处理,比如

  • ${#strings.toUpperCase(name)}
    

    把字符串改成全大写

  • ${#strings.toLowerCase(name)}
    

    把字符串改成全小写

  • ${#strings.arrayJoin(array,',')}
    

    把字符串数组合并成一个字符串,并以,连接,比如["a","b"]执行后会变成a,b

  • ${#strings.arraySplit(str,',')}
    

    把字符串分隔成一个数组,并以,作为分隔符,比如a,b执行后会变成["a","b"];如果abc没有匹配到,执行后会变成["abc"]

  • ${#strings.trim(str)}
    

    把字符串去空格,左右空格都会去掉

  • ${#strings.length(str)}
    

    得到字符串的长度,也支持获取集合类的长度

  • ${#strings.equals(str1,str2)}
    

    比较两个字符串是否相等

  • ${#strings.equalsIgnoreCase(str1,str2)}
    

    忽略大小写后比较两个字符串是否相等

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值