服务器渲染技术-Thymeleaf

1.基本介绍

官方在线文档:Read online 文档下载:Thymeleaf 3.1 PDF, EPUB, MOBI

Thymeleaf 是什么

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

  2. Thymeleaf 是一个跟 Velocity、FreeMarker 类似的模板引擎,可完全替代 JSP

  3. Thymeleaf 是一个 Java 类库,是一个xml/ xhtml/ html5的模板引擎,可以作为 mvc 的 web 应用的 view 层

Thymeleaf 的优点

  1. 实现 JSTL、OGNL 表达式效果,语法类似,上手快
  2. Thymeleaf 模板页面无需服务器渲染,也可以被浏览器运行,页面简洁
  3. SpringBoot 支持 FreeMarker、Thymeleaf、Veocity

Thymeleaf 的缺点

  1. Thymeleaf 并不是一个高性能的引擎,适用于单体应用
  2. 如果要做一个高并发的应用,选择前后分离更好,比如 Vue + SpringBoot

2.Thymeleaf机制

Thymeleaf 是服务器渲染技术,页面数据是在服务端进行渲染的

例如:某个页面被请求,其中有一段Thymeleaf代码,则 thymeleaf 模板引擎完成处理之后(在服务端完成),才会将页面结果返回。因此使用Thymeleaf,并不是前后端分离。

3.语法

3.1表达式

1.表达式一览

表达式名称 语法 用途
变量取值 ${...} 获取请求域、session域、对象等值
选择变量 *{...} 获取上下文对象值
消息 #{...} 获取国际化等值
链接 @{...} 生成链接
片段表达式 ~{...} jsp:include 作用,引入公共页面片段

2.字面量

文本值:'jack', 'hello', ...

数字:10, 5, 36.8, ...

布尔值:true,false

空值:null

变量:name, age, ...(变量名不能有空格)

3.文本操作

字符串拼接:+

变量替换:|age=${age}|

3.2运算符

1.数学运算

运算符:+,-,*,/,%

2.布尔运算

运算符:and,or

一元运算:!,not

3.比较运算

比较:>,<,>=,<=(gt,lt,ge,le)

等式:==,!=(eq,ne)

4.条件运算

If-then:(if)?(then)

If-then-else:(if)?(then):(else)

Default:(value)?:(defaultvalue)

3.3th属性

html有的属性,Thymeleaf基本都有,而常用的属性大概有七八个。其中th属性执行的优先级从1~8,数字越小优先级越高。

  • th:fragment

    声明代码块,方便被 th:insert 引用。优先级为 order=8

  • th:text

    设置当前元素的文本内容,相同功能的还有 th:utext,两者的区别在于前者不会转义 html 标签,而后者会。优先级为 order=7

  • th:value

    设置当前元素的 value 值,类似修改指定属性的还有 th:src,th:href。优先级为 order=6

  • th:attr

    修改任意属性,实际开发中使用较少,因为有丰富的其他th属性帮忙,类似的还有th:attrappend,th:attrprepend。优先级为 order=5

  • th:object

    声明变量,一般和 *{} 一起配合使用,达到偷懒效果。优先级 order=4

  • th:if

    条件判断,类似的还有 th:unless,th:switch,th:case。优先级为 order=3

  • th:each

    遍历循环元素,和 th:text 或 th:value 一起使用。注意该属性修饰的标签位置。优先级为 order=2

  • th:insert

    代码块引入,类似的还有 th:replace,th:include。三者的区别较大,若使用不当会破坏html结构,当用于公共代码块提取的场景,优先级为 order=1

3.4迭代

教程:使用百里香叶 (thymeleaf.org)

在前端页面中,总是出现需要遍历集合中的元素以展示所有信息的场景。Thymeleaf标准方言为我们提供了一个有用的属性:th:each

假设后台控制器添加了一个商品列表的属性 prods。然后,我们使用 th:each 在模板中使用来遍历产品列表:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Good Thymes Virtual Grocery</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" media="all"
href="../../../css/gtvg.css" th:href="@{/css/gtvg.css}" />
</head>
<body>
<h1>Product list</h1> <table>
<tr>
<th>NAME</th>
<th>PRICE</th>
<th>IN STOCK</th>
</tr>
<tr th:each="prod : ${prods}">
<td th:text="${prod.name}">Onions</td>
<td th:text="${prod.price}">2.41</td>
<td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
</tr>
</table> <p>
<a href="../home.html" th:href="@{/}">Return to home</a>
</p>
</body>
</html>

prod : ${prods} 属性的含义为:循环 \({prods} 属性的每一个元素。\){prods} 为被迭代变量,prod 为迭代变量,即当前循环的元素。

需要注意的是,prod 为迭代变量的作用域为 <tr>元素,可用于其内部标记 <td>

3.5条件运算

例如:

<a href="comments.html"
th:href="@{/product/comments(prodId=${prod.id})}"
th:if="${not #lists.isEmpty(prod.comments)}">view</a>

这将创建一个指向评论页面(带有 URL )的链接,并将参数设置为产品的参数,但前提是产品有任何评论。/product/comments prodId id

还有一种方法可以使用 Java 中的等效开关结构有条件地显示内容:switch-case-default

<div th:switch="${user.role}">
<p th:case="'admin'">User is an administrator</p>
<p th:case="#{roles.manager}">User is a manager</p>
<p th:case="*">User is some other thing</p>
</div>

3.6注意事项

  1. 使用Thymeleaf语法首先要声明名称空间:xmlns:th="http://www.thymeleaf.org"
  2. 设置文本 th:text,设置input的值用 th:value,循环输出用 th:each,条件判断用 th:if,插入代码块用 th:insert,定义代码块用 th:fragment,声明变量用 th:object
  3. th:each 的用法需要格外注意,如果你要循环一个div中的p标签,则 th:each 属性必须放在p标签上。若你将其放在div上,循环的将是整个div
  4. 变量表达式中提供了很多的内置方法,该内置方法是用#开头,不要和#{}混淆。

4.综合案例

  • 需求:使用 SpringBoot+Thymeleaf 完成简单的用户登录-列表功能。

    1. 如果没有登录就访问管理页面,提示非法访问,需要登录
    2. 如果登录成功,显示登录名称,以及用户列表
    3. 为了简化,这里就不连数据库了,使用Javabean代替数据

注意:这里的thymeleaf的templates目录不能直接访问,是因为SpringBoot默认可以访问的静态资源路径没有templates,因此除了上面请求转发到资源的方法外,也可以配置静态资源的访问路径:

spring:
web:
resources:
static-locations: [classpath:/static/,classpath:/templates/]

或者在配置类中配置(略)。

4.1代码实现

(1)创建 SpringBoot 项目,引入基本的库文件

<!--导入SpringBoot父工程-->
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.5.3</version>
</parent> <dependencies>
<!--导入场景启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency> <!--引入thymeleaf-starter:项目会自动完成配置,相关类会自动注入容器中-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>

(2)创建 login.html 和 manage.html 和静态图片到指定目录(templates目录,该目录不能直接访问)

login.html

<!DOCTYPE html>
<!--引入命名空间-->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body bgcolor="#CED3FE">
<div style="text-align: center">
<h1>用户登录</h1>
<hr/>
<img src="data:images/login.jpg" width="35"/>
<!--th:action="@{/login}"可以替换#-->
<form action="#" th:action="@{/login}" method="post">
<label style="color: red" th:text="${msg}"></label><br/>
用户名:<input type="text" style="width: 150px" name="name"/><br/><br/>
密 码:<input type="password" style="width: 150px" name="password"/><br/><br/>
<input type="submit" value="登录"/>
<input type="reset" value="重新填写"/>
</form>
</div>
</body>
</html>

manage.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>管理后台</title>
</head>
<body bgcolor="#CED3FE">
<a href="#" th:href="@{/}">安全退出</a>
<!--行内取法,使用双层中括号-->
欢迎您:[[${session.loginAdmin.name}]]
<hr/>
<h1>管理雇员</h1>
<div style="position: center ">
<table border="1px" cellspacing="0" bordercolor="green" style="width: 700px">
<tr bgcolor="pink">
<td>id</td>
<td>name</td>
<td>age</td>
<td>pwd</td>
<td>email</td>
</tr>
<!--循环展示-->
<tr bgcolor="#ffc0cb" th:each="user:${users}">
<td th:text="${user.id}">a</td>
<td th:text="${user.name}">b</td>
<td th:text="${user.age}">c</td>
<td th:text="${user.password}">d</td>
<td th:text="${user.email}">e</td>
</tr>
</table>
<br/>
</div>
<hr/>
</body>
</html>

(3)Javabean

Admin.java

package com.li.thymeleaf.bean;

import lombok.Data;

/**
* @author 李
* @version 1.0
*/
@Data
public class Admin {
private String name;
private String password;
}

User.java

package com.li.thymeleaf.bean;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor; /**
* @author 李
* @version 1.0
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer id;
private String name;
private Integer age;
private String password;
private String email;
}

(4)控制器Controller

IndexController

package com.li.thymeleaf.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping; /**
* @author 李
* @version 1.0
*/
@Controller
public class IndexController {
//编写方法,转发到登录页
@GetMapping(value = {"/", "/login"})
public String login() {
//因为我们引入了starter-thymeleaf,这里会直接
//使用视图解析到thymeleaf模板文件下的adminLogin.html
return "adminLogin";
}
}

AdminController

package com.li.thymeleaf.controller;

import com.li.thymeleaf.bean.Admin;
import com.li.thymeleaf.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.List; /**
* @author 李
* @version 1.0
*/
@Controller
public class AdminController {
/**
* 响应用户登录请求
*
* @param admin 自定义对象参数
* @param session 将获取的admin信息放入session中(登录成功)
* @param model model的数据会自动放入request域中传给下一个页面(登录失败)
* @return
*/
@PostMapping("/login")//从请求方式区分,不会冲突
public String login(Admin admin, HttpSession session, Model model) {
//验证用户是否合法
if (StringUtils.hasText(admin.getName()) && "666".equals(admin.getPassword())) {//合法
//将登陆用户保存到session中
session.setAttribute("loginAdmin", admin);
//应使用重定向(用请求转发刷新页面会重复提交表单),这里的重定向是到mainPage方法,而不是直接到页面。
return "redirect:manage.html";
} else {//不合法,返回重新登录
model.addAttribute("msg", "用户名或密码错误!");
return "adminLogin";
}
} //处理用户请求到manage.html
@GetMapping("/manage.html")
public String mainPage(Model model, HttpSession session) {
//先校验(这里暂时使用session验证,后面可以统一使用拦截器)
Object loginAdmin = session.getAttribute("loginAdmin");
if (loginAdmin != null) {//说明登陆过
//模拟用户数据
List<User> users = new ArrayList<>();
users.add(new User(1, "关羽", 555, "1234", "gy@qq.com"));
users.add(new User(2, "张飞", 455, "12345", "zf@qq.com"));
users.add(new User(3, "赵云", 344, "12346", "zy@qq.com"));
users.add(new User(4, "马超", 300, "12347", "mc@qq.com"));
users.add(new User(5, "黄忠", 666, "12348", "hz@qq.com"));
//放入到request域中(model中的数据会自动放入到request域中)
model.addAttribute("users", users);
return "manage";//这里才是真正视图解析到 templates/manage.html
} else {//说明没有登录过,拒绝访问manage页面
model.addAttribute("msg", "你没有登录/请登录!");
return "adminLogin";
}
}
}

(5)启动类

package com.li.thymeleaf;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; /**
* @author 李
* @version 1.0
*/
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}

(6)测试

  • 未经登录直接访问manage.html

  • 登录测试

4.2练习

  1. 把前面接收参数相关注解、自定义转换器、处理JSON、内容协商相关代码和案例过一遍

  2. 将Thymeleaf用户管理改为妖怪列表,字段做相应的改变,进行练习

    • Monster [id,name,skill,age,salary,birth]

day08-2-Thymeleaf的更多相关文章

  1. spring boot(四):thymeleaf使用详解

    在上篇文章springboot(二):web综合开发中简单介绍了一下thymeleaf,这篇文章将更加全面详细的介绍thymeleaf的使用.thymeleaf 是新一代的模板引擎,在spring4. ...

  2. Thymeleaf

    1.在html顶部添加 <html xmlns:th="http://www.thymeleaf.org"> 2.url表达式 @{...} <link rel= ...

  3. Thymeleaf 模板的使用

    Thymeleaf是现代化服务器端的Java模板引擎,不同与JSP和FreeMarker,Thymeleaf的语法更加接近HTML,并且也有不错的扩展性.详细资料可以浏览官网.本文主要介绍Thymel ...

  4. vert.x学习(三),Web开发之Thymeleaf模板的使用

    在vert.x中使用Thymeleaf模板,需要引入vertx-web-templ-thymeleaf依赖.pom.xml文件如下 <?xml version="1.0" e ...

  5. 页面上使用 Thymeleaf 的内联js不当造成了 java.lang.StackOverflowError: null 问题

    由于在页面上内联js使用不当,从而在从 Controller 跳转到页面时发生了以下错误: java.lang.StackOverflowError: null at org.thymeleaf.ut ...

  6. Thymeleaf 与 Javascript

    在 javascript 代码中使用 Thymeleaf 模板引擎: <script th:inline="javascript"> $("#content& ...

  7. Thymeleaf+SpringMVC,如何从模板中获取数据

    Thymeleaf+SpringMVC,如何从模板中获取数据 在一个典型的SpringMVC应用中,带@Controller注解的类负责准备数据模型Map的数据和选择一个视图进行渲染.这个模型Map对 ...

  8. Thymeleaf+Spring整合

    前言 这个教程介绍了Thymeleaf与Spring框架的集成,特别是SpringMvc框架. 注意Thymeleaf支持同Spring框架的3.和4.版本的集成,但是这两个版本的支持是封装在thym ...

  9. thymeleaf常用标签

    1. th:checked ,th:selected标签<input type="radio" value="M" name="gender&q ...

  10. thymeleaf的常见用法

    1,th:属性名="",就可以直接修改控件的属性,比如 <input th:type="button" th:name="xinxin" ...

随机推荐

  1. 使用symbolicatecrash工具符号化Crash日志

    对于打包上线的APP,或者打包测试的APP,出现了崩溃并不能方便的把手机链接到电脑使用XCode自动符号化,此时手动符号化就是重要的选项. 1.查找符号化工具symbolicatecrash find ...

  2. 哈希表(HashMap)与字符串哈希

    哈希表 哈希表是一种通过映射来快速查找的数据结构.其通过键值对(key-value)来存储.一个数据通过哈希函数的运算来生成一个属于他自己的键值,尔后将其与键值绑定.当我们想查找这个数据时,就可以直接 ...

  3. 小知识:如何修改TFA下的OSW数据保留时间

    在Oracle社区可以搜索到这样的问题: How to change oswatcher retention when running under TFA 但很遗憾该问题目前也没有给出确切答复. 其实 ...

  4. 我的微软 MVP 之路

    目录 微软 MVP 大礼包 我的社区经历 如何成为微软 MVP 微软 MVP 权益 总结 微软 MVP 大礼包 今天,我收到了飘洋过海的微软 MVP 大礼包,内心无比激动,礼包内包含了一座水晶奖杯,一 ...

  5. Python-字符串format方法指定参数

    一.字符串的format方法有几种指定参数的方式:(1)按照位置传参(默认方式),传入的参数与{}一一对应(2)关键字传参,关键字(keyword)传递是根据每个参数的名字传递参数.关键字并不用遵守位 ...

  6. 浅谈一下对于 js 中的 this 的理解

    浅谈一下对于 js 中的 this 的理解 对于 this 值的定义: 简单来说 this 是一个对象,这个对象具体的值是什么,取决于运行时的环境,即代码执行时的环境. MDN: 当前执行上下文( g ...

  7. MQTT-基础理念

    MQTT与HTTP的区别 HTTP协议是客户端与服务端直连请求与响应 MQTT是基于发布订阅模型的轻量级的消息传输协议 MQTT能力 发布:Publish 订阅:Subscribe 代理:Broker ...

  8. 《系列二》-- 10、initialize-初始化bean

    目录 initializeBean 方法源码如下 二.重要操作 2.1 应用 Aware 2.2 applyBeanPostProcessorsBeforeInitialization: 2.3 in ...

  9. pikachu sql inject header 注入

    使用admin登录 显示以下内容 朋友,你好,你的信息已经被记录了:点击退出 你的ip地址:172.17.0.1 你的user agent:Mozilla/5.0 (X11; Ubuntu; Linu ...

  10. django自定义模型管理器Manager及方法

    django自定义模型管理器Manager及方法 自定义管理器(Manager) 在语句Book.objects.all()中,objects是一个特殊的属性,通过它来查询数据库,它就是模型的一个Ma ...