thymeleaf简明教程
前言
thymeleaf是spring-boot推荐使用的模板引擎,之前因为时间关系,一直没有机会去一探究竟,国庆期间,正好有了那么一点时间,赶紧拿来研究一下。
本教程不做深入的探讨,目标是能让一个没有接触过thymeleaf的开发者,能在很短的时间内快速上手拿来做开发。
当然,本教程并不完整,之后再补充。
什么是thymeleaf
thymeleaf是一款用于在java中生成动态页面的程序:用于将静态模板页面组合绑定一定的数据,生成一个新页面。这样的程序,通常也叫做模板引擎。
一般来说,一个模板页面是一个类似纯html页面的文件,其中的与传递进来的数据进行交互的关键位置,会有本模板引擎可以解析的占位符。占位符的作用有:
- 将传递进来的数据直接替换展示
- 将传递进来的数据集合进行循环展示
- 将传递进来的数据进行判断之后展示
- 模板引擎支持的表达式 等等。
thymeleaf与freemarker等模板引擎相比,区别在于,他的占位符是直接是html标签,或者是标签的一个或多个属性。 即使没有数据传进来,也能当成一般的网页被浏览器解析,所以能完全做到前端后一起开发。
依赖
按照官方的推荐,用在spring-boot的项目中,版本号由spring-boot-start-parent管理
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
</parent>
复制代码
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
复制代码
第一个页面
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>First page</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p th:text="${welcome}">Welcome to thymeleaf world!</p>F
</body>
</html>
复制代码
注意这里的xmlns:th
<html xmlns:th="http://www.thymeleaf.org">
复制代码
一般来说,都需要加上这么一行,表示thymeleaf的命名空间。这里的xmlns:th指的是将thymeleaf的命名空间的名字命名为th,这个符号和之后所用的th一致。
th:text
:在th后面加上一个冒号,并附加特定的字符组合,这个thymeleaf定义的占位符是构建thymeleaf页面的基础。之后我们可以看到许多这样的占位符。
${welcome}
:${}
这个占位符是thymeleaf非常关键的符号之一,用于变量的解析。
使用idea构建项目
为了看到程序的运行效果,这里使用官方的starter来配置一个项目
打开网址:start.spring.io/
选择对应的版本,并选择对应的依赖,导入到idea中。
pom如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.github.jzoom.springboot</groupId>
<artifactId>thymeleafdemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>thymeleafdemo</name>
<url>http://maven.apache.org</url>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
</parent>
<!-- Additional lines to be added here... -->
<!-- (you don't need this if you are using a .RELEASE version) -->
<repositories>
<repository>
<id>spring-snapshots</id>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<url>https://repo.spring.io/snapshot</url>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<url>https://repo.spring.io/milestone</url>
</pluginRepository>
</pluginRepositories>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>
</project>
复制代码
编辑模板页面
在resources中新建templates文件夹,并新建index.html,并编辑,将上面的代码拷贝到这个文件并保存。
编写Controller
package com.example.thymeleafdemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.HashMap;
import java.util.Map;
@Controller
@SpringBootApplication
public class ThymeleafdemoApplication {
public static void main(String[] args) {
SpringApplication.run(ThymeleafdemoApplication.class, args);
}
@RequestMapping
public String index(Model model){
model.addAttribute("welcome","Hello world!");
return "index";
}
}
复制代码
打开浏览器查看:http://localhost:8080
设置自动编译
到这里,已经可以正常运行,但是每次修改后都要重启服务,这个是无法容忍的,所以这里进行几项设置:
-
将idea设置为自动编译 参考这里
-
修改pom,新增devtool
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.github.jzoom.springboot</groupId>
<artifactId>thymeleafdemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>thymeleafdemo</name>
<url>http://maven.apache.org</url>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
</parent>
<!-- Additional lines to be added here... -->
<!-- (you don't need this if you are using a .RELEASE version) -->
<repositories>
<repository>
<id>spring-snapshots</id>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<url>https://repo.spring.io/snapshot</url>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<url>https://repo.spring.io/milestone</url>
</pluginRepository>
</pluginRepositories>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<!--自动编译-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
复制代码
- 设置关闭缓存
修改配置,增加一行
spring.thymeleaf.cache=false
复制代码
这样就可以在修改了任何一个文件之后,只要刷新一下页面就可以看到效果了。
循环
上面的例子比较详细,下面只是列出相对简单的代码。
新增实体类:
public class Product {
// 编号
private Long id;
// 标题
private String title;
//价格(分,需要展示为元)
private int price;
// 折扣率(百分比,0.xx)
private float discountPercent;
// 这个方法用于格式化价格
public String formatedPrice(){
return String.format("%.02f",(float)price/100);
}
//...略
}
复制代码
编辑ProductService
@Component
public class ProductService {
public List<Product> findAll(){
return Arrays.asList(new Product(1L,"商品1",8500,0.9f),
new Product(2L,"商品2",10050,1.0f),
new Product(3L,"商品3",3080,0.85f));
}
}
复制代码
编辑Controller
@RequestMapping
public String index(Model model){
model.addAttribute("welcome","Hello world!");
model.addAttribute("products",productService.findAll());
return "index";
}
复制代码
编辑index.html
<ul>
<li th:each="product:${products}">
<span th:text="${product.id}">编号</span>
<span th:text="${product.title}">标题</span>
<span th:text="${product.formatedPrice()}">价格</span>
<span th:text="${product.discountPercent*100+'%'}">折扣</span>
</li>
</ul>
复制代码
分支
<span th:if="${product.discountPercent<=0.9}">热销</span>
复制代码