文章目录
- JSP 的替代者:Thymeleaf
- Thymeleaf 简介
- 快速上手
- pom.xml
- application.properties
- 一个简单的页面
- Controller
- 常用语法
- 赋值、字符串拼接
- 条件判断 If/Unless
- for 循环
- URL 处理
- 三目运算
- switch 选择
JSP 的替代者:Thymeleaf
Thymeleaf 简介
Thymeleaf 旨在提供一个优雅的、高度可维护的创建模板的方式。为了实现这一目标,Thymeleaf 建立在自然模板的概念上,将其逻辑注入到模板文件中,不会影响模板设计原型,从而改善了设计的沟通,弥合了设计和开发团队之间的差距。
Thymeleaf 从设计之初就遵循 Web 标准——特别是 HTML 5 标准,如果需要,Thymeleaf 允许创建完全符合 HTML 5 验证标准的模板。
Spring Boot 体系内推荐使用 Thymeleaf 作为前端页面模板,并且 Spring Boot 2.0 中默认使用 Thymeleaf 3.0,性能提升幅度很大。
与其他的模板引擎(JSP、Velocity、FreeMarker)相比较,它有如下三个极吸引人的特点:
-
Thymeleaf 可以在浏览器查看页面的静态效果。
-
Thymeleaf 开箱即用的特性。它支持标准方言和 Spring 方言,可以直接套用模板实现 JSTL、OGNL 表达式效果。
-
Thymeleaf 方便与 SpringMVC 集成。
对比 Velocity、FreeMarker 与 Thymeleaf 打印出同一条消息:
Velocity: <p>$message</p>
FreeMarker: <p>${message}</p>
Thymeleaf: <p th:text="${message}">Hello World!</p>
上面我们可以看出来 Thymeleaf 的作用域在 HTML 标签内,类似标签的一个属性来使用,这就是它的特点。
快速上手
pom.xml
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
application.properties
spring.thymeleaf.cache=falselogging.level.root=INFO
logging.level.xxx.yyy.zzz=DEBUG
logging.pattern.console=%clr(%5level) \%clr(|){faint} \%clr(%-40.40logger{39}){cyan} \%clr(:){faint} \%m%n
关闭 Thymeleaf 的缓存。不然在开发过程中修改页面不会立即生效需要重启,生产可配置为 true 。
一个简单的页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"/><title>Hello</title>
</head>
<body><h1 th:text="${message}">Hello World</h1></body>
</html>
所有使用 Thymeleaf 的页面『必须』在 HTML 标签声明 Thymeleaf:
<html xmlns:th="http://www.thymeleaf.org">
表明页面使用的是 Thymeleaf 语法。否则,开发工具会认为你在 html 中缩写的 th:
是语法错误。
Controller
@Controller
public class HelloController {@RequestMapping("/")public String index(ModelMap map) {map.addAttribute("message", "http://www.baidu.com");return "hello";}}
常用语法
赋值、字符串拼接
-
赋值和拼接:
<p th:text="${userName}">我是默认值</p> <span th:text="'Welcome to our application, ' + ${userName} + '!'">我是默认值</span>
-
字符串拼接还有另外一种简洁的写法(推荐):
<span th:text="|Welcome to our application, ${userName}!|">我是默认值</span>
-
string.html 页面:
... <body><div ><h1>text</h1><p th:text="${userName}">我是默认值</p><span th:text="'Welcome to our application, ' + ${userName} + '!'">我是默认值</span><br/><span th:text="|Welcome to our application, ${userName}!|">我是默认值</span></div> </body>
-
后端传值:
@RequestMapping("/string") public String string(ModelMap map) {map.addAttribute("userName", "baidu");return "string"; }
条件判断 If/Unless
Thymeleaf 中使用 th:if 和 th:unless 属性进行条件判断,在下面的例子中, <a>
标签只有在 th:if 中条件成立时才显示:
-
示例:
<a th:if="${flag == 'yes'}" th:href="@{http://www.163.com/}">163</a><a th:unless="${flag != 'no'}" th:href="@{http://www.baidu.com/}">baidu</a>
th:unless 与 th:if 恰好相反,只有表达式中的条件立,才会显示其内容。
-
页面 if.html:
<body><div ><h1>If/Unless</h1><a th:if="${flag == 'yes'}" th:href="@{http://www.163.com/}">163</a><br/><a th:unless="${flag != 'no'}" th:href="@{http://www.baidu.com/}">baidu</a></div> </body>
-
后端传值:
@RequestMapping("/if") public String ifunless(ModelMap map) {map.addAttribute("flag", "yes");return "if"; }
for 循环
for 循环在我们项目中使用的频率太高,一般结合前端的表格来使用。
-
在后端定义一个列表,以键
users
,传递到前端:@RequestMapping("/list") public String list(ModelMap map) {User user1 = new User("大牛",12,"123456");User user2 = new User("小牛",6,"123563");User user3 = new User("纯洁的微笑",66,"666666");List<User> list = new ArrayList<User>();list.add(user1);list.add(user2);list.add(user3);map.addAttribute("users", list);return "list"; }
-
list.html 进行数据展示:
... <body><div ><h1>for 循环</h1><table><tr th:each="user,iterStat : ${users}"><td th:text="${user.name}">neo</td><td th:text="${user.age}">6</td><td th:text="${user.pass}">213</td><td th:text="${iterStat.index}">index</td></tr></table></div> </body>
iterStat 称作状态变量,属性有:
属性 | 说明 index | 当前迭代对象的 index (从 0 开始计算)count | 当前迭代对象的 index (从 1 开始计算)size | 被迭代对象的大小current | 当前迭代变量 even/odd | 布尔值,当前循环是否是偶数/奇数(从 0 开始计算)first | 布尔值,当前循环是否是第一个last | 布尔值,当前循环是否是最后一个
-
页面展示效果
for 循环大牛 12 123456 0 小牛 6 123563 1 纯洁的微笑 66 666666 2
URL 处理
需要特别注意的是 Thymeleaf 对于 URL 的处理是通过语法 @{…} 来处理的。如果需要 Thymeleaf 对 URL 进行渲染,那么务必使用 th:href、th:src 等属性。
-
示例:
<a th:href="@{http://www.baidu.com/{xxx}(xxx=${type})}">link1</a> <a th:href="@{http://www.baidu.com/{pageId}/can-use-springcloud.html(pageId=${pageId})}">view</a> <form th:action="@{/order}"> </form>
-
几点说明:
上例中 URL 最后的
(pageId=${pageId})
表示将括号内的内容作为 URL 参数处理,该语法避免使用字符串拼接,大大提高了可读性;@{...}
表达式中可以通过{pageId}
访问 Context 中的pageId
变量;@{/order}
是 Context 相关的相对路径,在渲染时会自动添加上当前 Web 应用的 Context 名字,假设 context 名字为 app,那么结果应该是/app/order
。 -
页面内容:
... <body><div ><h1>URL</h1><a th:href="@{http://www.baidu.com/{type}(type=${type})}">link1</a><br/><a th:href="@{http://www.baidu.com/{pageId}/can-use-springcloud.html(pageId=${pageId})}">view</a><br/><div th:style="'background:url(' + @{${img}} + ');'"><br/><br/><br/></div></div> </body>
-
后端程序:
@RequestMapping("/url") public String url(ModelMap map) {map.addAttribute("type", "link");map.addAttribute("pageId", "springcloud/2017/09/11/");map.addAttribute("img", "http://www.baidu.com/assets/images/neo.jpg");return "url"; }
三目运算
三目运算是我们常用的功能之一,普遍应用在各个项目中。
-
例如:
<input th:value="${name}"/> <input th:value="${age gt 30 ? '中年':'青年'}"/>
-
说明:
表示如果 age 大于 30 则输入框中显示中年,否则显示青年。
-
三目运算符关键字:
关键字 | 说明 gt | great than(大于)ge | great equal(大于等于)eq | equal(等于)lt | less than(小于)le | less equal(小于等于)ne | not equal(不等于)
-
结合三目运算也可以将上面的 if else 改成这样:
<a th:if="${flag eq 'yes'}" th:href="@{http://www.baidu.com/}"> 百度 </a>
-
页面内容:
... <body><div ><h1>EQ</h1><input th:value="${name}"/><br/><input th:value="${age gt 30 ? '中年年:'青年'}"/><br/><a th:if="${flag eq 'yes'}" th:href="@{http://www.baidu.com/}"> 百度 </a></div> </body>
-
后端程序:
@RequestMapping("/eq") public String eq(ModelMap map) {map.addAttribute("name", "neo");map.addAttribute("age", 30);map.addAttribute("flag", "yes");return "eq"; }
-
页面效果:
EQ neo 青年 百度
单击
百度
链接会跳转到:http://www.baidu.com/
地址。
switch 选择
switch/case 多用于多条件判断的场景下。
-
以性别举例:
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"><head><meta charset="UTF-8"></meta><title>Example switch</title></head><body><div ><div th:switch="${gender}"><p th:case="'woman'">她是一个姑娘...</p><p th:case="'man'">他是一个男生!</p><!-- *: case的默认的选项 --><p th:case="*">未知性别。</p></div></div></body> </html>
-
后端程序:
@RequestMapping("/switch") public String switchcase(ModelMap map) {map.addAttribute("gender", "woman");return "switch"; }
在浏览器中输入网址:http://localhost:8080/switch
。
-
页面展示效果如下:
她是一个姑娘...
可以在后台改 gender 的值来查看结果。