Thymeleaf 简介和使用
Thymeleaf 简介
介绍
Thymeleaf 是面向 Web 和独立环境的现代服务器端 Java 模板引擎,能够处理 HTML、XML、JavaScript、CSS 甚至纯文本。
Thymeleaf 旨在提供一个优雅的、高度可维护的创建模板的方式。为了实现这一目标,Thymeleaf 建立在自然模板的概念上,将其逻辑注入到模板文件中,不会影响模板设计原型,从而改善了设计的沟通,弥合了设计和开发团队之间的差距。
Thymeleaf 从设计之初就遵循 Web 标准一特别是 HTML5 标准,如果需要,Thymeleaf 允许创建完全符合 HTML5 验证标准的模板。
Spring Boot 体系内推荐使用 Thymeleaf 作为前端页面模板,并且 Spring Boot 2.0 中默认使用 Thymeleaf3.0,性能提升幅度很大。
特点
简单说, Thymeleaf 是一个跟 Velocity、FreeMarker 类似的模板引擎,它可以完全替代 JSP。
与其他的模板引擎相比较,它有如下三个极吸引人的特点。
● Thymeleaf 在有网络和无网络的环境下皆可运行,即它可以让美工在浏览器查看页面的静态效果,也可以让程序员在服务器查看带数据的动态页面效果。这是由于它支持 HTML 原型,然后在 HTML 标签里增加额外的属性来达到模板 + 数据的展示方式。浏览器解释 HTML 时会忽略未定义的标签属性,所以 Thymeleaf 的模板可以静态地运行: 当有数据返回到页面时,Thymeleaf 标签会动态地替换掉静态内容,使页面动态显示。
● Thymeleaf 开箱即用的特性。它支持标准方言和Spring方言,可以直接套用模板实现 JSTL、OGNL 表达式效果,避免每天套模板、改 JSTL、改标签的困扰。同时开发人员也可以扩展和创建自定义的方言。
● Thymeleaf 提供 Spring 标准方言和一个与 SpringMVC 完美集成的可选模块,可以快速地实现表单绑定、属性编辑器、国际化等功能。
我们可以对比一下 Thymeleaf 和常用的模板引擎: Velocity、 Freemaker, 和其他模板一些不同的是,它使用了自然的模板技术。这意味着 Thymeleaf 的模板语法并不会破坏文档的结构,模板依旧是有效的 XML 文档。模板还可以用做工作原型,Thymeleaf 会在运行期替换掉静态值。Velocity 与FreeMarker 则是连续的文本处理器。
Thymeleaf 使用
- 构建项目:
- 相关依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.18</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
</dependency>
</dependencies>
- application.properties 添加配置:
#配置数据源相关信息
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/stu?useUnicode=true&characterEncoding=utf-8
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root
spring.thymeleaf.cache=false
spring.thymeleaf.cache=false 是关闭 Thymeleaf 的缓存,不然在开发过程中修改页面不会立刻生效需要重新重启,生产可配置为 true。
- 项目结构
启动类:
@SpringBootApplication
@MapperScan("com.example.demo.mapper")
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
User:
@Data
@TableName("user")
public class User implements Serializable {
@TableId(type = IdType.AUTO)
@TableField("user_id")
private Long userId;
@TableField("user_name")
private String userName;
@TableField("user_password")
private String userPassword;
@TableField("user_role_id")
private Long userRoleId;
@TableField("user_flag")
private Integer userFlag;
UserMapper:
public interface UserMapper extends BaseMapper<User> {
}
UserService:
public interface UserService {
public User login(String userName, String userPassword);
public int addUser(User user);
public int updateUser(User user);
public int deleteUser(Long UserId);
public User getUser(Long UserId);
public List<User> findAllUser();
}
UserServiceImpl:
@Service("userService")
public class UserSerivceImpl implements UserService {
@Resource
UserMapper userMapper;
@Override
public User login(String userName, String userPassword) {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("user_name", userName);
wrapper.eq("user_password", userPassword);
return userMapper.selectOne(wrapper);
}
@Override
public int addUser(User user) {
return userMapper.insert(user);
}
@Override
public int updateUser(User user) {
return userMapper.updateById(user);
}
@Override
public int deleteUser(Long userId) {
return userMapper.deleteById(userId);
}
@Override
public User getUser(Long userId) {
return userMapper.selectById(userId);
}
@Override
public List<User> findAllUser() {
return userMapper.selectList(null);
}
}
- 控制器开发
在 com.example.demo.controller 包下创建 ExampleController
@Controller
public class ExampleController {
@Resource
private UserService userService;
@GetMapping(value = "/hello/{id}")
public String getUser(@PathVariable("id") Long userId, Model model){
User user = userService.getUser(userId);
model.addAttribute("user",user);
return "demo/hello";
}
- 页面开发
在 resources/templates 下创建 demo 目录, 在 demo 目录下新建 hello.html (HTML 5 file)
<!DOCTYPE html>
<html lang="en" xmlns:th=":http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Hello</title>
</head>
<body>
欢迎您,<span th:text="${user.userName}">name</span>
</body>
</html>
所有使用 Thymeleaf 的页面必须在 HTML 标签声明 Thymeleaf:
< html lang=“en” xmlns:th=":http://www.thymeleaf.org" >
- 运行访问
核心语法
表达式
- 变量表达式: ${…}
- 选择或星号表达式: *{…}
- 文字国际化表达式: #{…}
- URL 表达式: @{}
- 片段表达式: ~{…}
常用标签
页面布局
需要引入依赖:
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
</dependency>
基础操作
在 resources/templates/demo/layout 目录下新建 footer .html, 代码如下:
<footer th:fragment="copyright">
@2020 爱唯逸科技有限公司
</footer>
在 resources/templates/demo 目录下新建 index.html, 代码如下:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head >
<meta charset="UTF-8">
<title>title</title>
</head>
<body>
<div th:insert="demo/layout/footer::copyright"></div>
<div th:replace="demo/layout/footer::copyright"></div>
</body>
</html>
语法:demo/layout/footer::copyright, 其中 demo/layout 是文件夹地址, footer是文件名, copyright 是指定义的代码片段。
控制器添加访问入口运行如下:
th:insert 只是加载会保留父级标签, th:replace 是替换.
页面布局
在 resources/templates/demo/layout 目录下新建 lefter.html, 代码如下:
<lefter th:fragment="menu">
<h3>左侧菜单</h3>
</lefter>
在 resources/templates/demo/layout 目录下新建 header.html, 代码如下:
<header th:fragment="header">
<h3>头部</h3>
</header>
在 resources/templates/demo 目录下新建 fragment.html, 代码如下:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout">
<head>
<meta charset="UTF-8">
<title>布局</title>
</head>
<body>
<div>
<div th:include="demo/layout/header2::header" ></div>
<div th:include="demo/layout/lefter::menu"></div>
<div layout:fragment="content">content</div>
<div th:include="demo/layout/footer::copyright"></div>
</div>
</body>
</html>
控制器添加访问入口运行如下:
可以看出 fragment.html 页面已经成功地引入了页面的头部、左侧、尾部。接下来以 fragment.html 作为一个页面模板,任何页面想使用此布局时,只需要替换中间的 content 模块即可。在 templates/demo 目录下新建test.html进行测试, 代码如下:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout"
layout:decorate="demo/fragment">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div layout:fragment="content">
<h2>内容</h2>
</div>
</body>
</html>