SpringBoot集成Thymeleaf

Thymeleaf语法、页面静态化

Thymeleaf

Thymeleaf是用来开发web和独立环境项目的现代服务器端Java模板引擎。

  • 动静结合:Thymeleaf再有网无网络的环境下皆可运行
  • 开箱急用,多方言支持
  • 与SpringBoot完美整合

视图解析

ThymeleafViewResolver, 与解析JSP的InternalViewResolver类似,Thymeleaf也会根据前缀和后缀来确定模板文件的位置

1
2
3
4
5
6
7
@ConfigurationProperties(prefix = "spring.thymeleaf")
public class ThymeleafProperties {
/* 默认前缀 */
public static final String DEFAULT_PREFIX = "classpath:/templates/";
/* 默认后缀 */
public static final String DEFAULT_SUFFIX = ".html";
}

页面缓存

Thymeleaf默认会开启网页缓存,提高页面的并发能力,但会导致我们修改页面不会立即被展现。所以我们在开发中需要先禁用缓存:

1
spring.thymeleaf.cache=false	# 设置为不缓存

注意:在idea中,禁用缓存后,每次修改页面,还需要recompile一下页面,才能在刷新网页。

快速入门

  • 引入依赖
1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
  • HelloContorller.java
1
2
3
4
5
6
7
8
9
10
11
12
@Controller
public class HelloController {

@GetMapping("hello")
public ModelAndView hello() {
ModelAndView mv = new ModelAndView();
mv.addObject("msg", "hello thymeleaf!");
mv.setViewName("hello");

return mv;
}
}
  • hello.html
1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>hello</title>
</head>
<body>
<h2 th:text="${msg}">hello world</h2>
</body>
</html>
  • 访问该controller的地址,即可看到渲染结果

语法

${} @{} ||

  • ${} :变量表达式,获取Model中的变量值,ognl的语法。
  • @{}:url表达式
    • @{/user(id=1)}: /user?id=1
  • ||:双竖线中可以有普通字符串,也可以有变量表达式
    • |page-item ${page=1 ? 'disabled' : ''}|

th:text / th:utest

  • th:text 读到的值会格式化输出,可以防止HTML注入
  • th:utest 输出原始内容,可以渲染html代码

字面量

  • 字符串字面量:使用单引号引起来
  • 数字字面量:数字不需要任何特殊语法, 写的什么就是什么
  • 布尔字面量:true / false

自定义变量

频繁的使用${user.}来获取属性值会非常麻烦,因此Thymeleaf通过自定变量来解决这个问题

  • 再div标签上使用th:object=”${user}”获取user的值,并保存下来
  • 然后在该标签内部任意元素上,通过*{属性名}的方式,来获取对象中的属性值
1
2
3
4
5
<h2>User</h2>
<div th:object="${user}">
<h3>username: <span th:text="*{username}">username</span></h3>
<h3>password: <span th:text="*{password}">password</span></h3>
</div>

运算

支持算术运算、比较运算、条件运算。

需要注意:${}内部的是通过OGNL表达式引擎解析的,外部的才是通过Thymeleaf的引擎解析,因此运算符尽量放在${}外进行。

逻辑判断

  • th:if / th:else
  • th:switch / th:case:一旦有一个th:case成立,其它的则不再判断
1
2
3
4
5
<div th:switch="${user.role}">
<p th:case="'admin'">用户是管理员</p>
<p th:case="'manager'">用户是经理</p>
<p th:case="*">用户是别的玩意</p>
</div>

th:each循环遍历

1
2
3
4
5
<!-- stat循环状态对象 -->
<p th:each="user, stat : ${users}">
姓名:<span th:text="${user.name}"></span>
年龄:<span th:text="${user.age}"></span>
</p>

可以遍历一下类型:

  • Iterable,实现了Iterable接口的类
  • Enumeration,枚举
  • Interator,迭代器
  • Map,遍历得到的是Map.Entry
  • Array,数组及其它一切符合数组结果的对象

stat对象包含以下属性:

  • index,从0开始的角标
  • count,元素的个数,从1开始
  • size,总元素个数
  • current,当前遍历到的元素
  • even/odd,返回是否为奇偶,boolean值
  • first/last,返回是否为第一或最后,boolean值

方法

ognl表达式本身就支持方法调用,如:

1
2
<!-- 调用string的split方法 -->
<span th:text="${user.name.split(' ')[0]}">Jack</span>

内置对象

Thymeleaf中提供了一些内置对象,并且在这些对象中提供了一些方法,方便我们来调用。获取这些对象,需要使用#对象名来引用。

  • 一些环境相关对象
对象 作用
#ctx 获取Thymeleaf自己的Context对象
#requset 如果是web程序,可以获取HttpServletRequest对象
#response 如果是web程序,可以获取HttpServletReponse对象
#session 如果是web程序,可以获取HttpSession对象
#servletContext 如果是web程序,可以获取HttpServletContext对象
  • Thymeleaf提供的全局对象:
对象 作用
#dates 处理java.util.date的工具对象
#calendars 处理java.util.calendar的工具对象
#numbers 用来对数字格式化的方法
#strings 用来处理字符串的方法
#bools 用来判断布尔值的方法
#arrays 用来护理数组的方法
#lists 用来处理List集合的方法
#sets 用来处理set集合的方法
#maps 用来处理map集合的方法
  • 例子:显示当前日期
1
<h2 th:text="${#dates.format(#dates.createNow(), 'yyyy-MM-dd')}"></h2>

js模板

模板引擎不仅可以渲染html,也可以对JS中的进行预处理。而且为了在纯静态环境下可以运行,其Thymeleaf代码可以被注释起来:

1
2
3
4
5
6
<script th:inline="javascript">
const user = /*[[${user}]]*/ {};
const age = /*[[${user.age}]]*/ 20;
console.log(user);
console.log(age)
</script>
  • 在script标签中通过th:inline="javascript"来声明这是要特殊处理的js脚本

  • 语法结构:

    1
    const user = /*[[Thymeleaf表达式]]*/ "静态环境下的默认值";

    因为Thymeleaf被注释起来,因此即便是静态环境下, js代码也不会报错,而是采用表达式后面跟着的默认值。

页面静态化

概念

静态化是指把动态生成的HTML页面变为静态内容保存,以后用户的请求到来,直接访问静态页面,不再经过服务的渲染。

目前,静态化页面都是通过模板引擎来生成,而后保存到nginx服务器来部署。

常用的模板引擎比如:

  • Freemarker
  • Velocity
  • Thymeleaf

使用Thymeleaf实现

概念:

  • Context:thymeleaf运行上下文, 存放数据模型
    • 当与SpringBoot结合使用时,我们放入Model的数据就会被处理到Context,作为模板渲染的数据使用。
  • TemplateResolver:模板解析器,用来读取模板相关的配置
    • 当与SpringBoot结合时,TemplateResolver已经由其创建完成,并且各种配置也都有默认值。
  • TemplateEngine:模板引擎, 用来解析模板的引擎
    • SpringBoot中已经自动配置了模板引擎
    • 静态化方法:templateEngine.process("模板名", context, writer);

代码实现:

  • service
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public void createGoodsHtml(Long spuId, Map<String, Object> attributeMap) {
// 创建thymeleaf运行上下文
Context context = new Context();
// 设置参数
context.setVariables(attributeMap);

String filename = "C:\\ProgramFiles\\nginx-1.17.8\\html\\goods\\" + spuId + ".html";
try(
FileWriter writer = new FileWriter(filename)
) {
// 生成html文件
templateEngine.process("goods", context, writer);
} catch (Exception e) {
log.error("[商品详情页{}.html静态化失败]: ", spuId, e);
}
}
  • controller
1
2
3
4
5
6
7
8
9
10
@GetMapping("/{id}.html")
public String toGoodsPage(@PathVariable(value = "id") Long spuId, Model model) {
Map<String, Object> attributeMap = goodsService.queryGoodsbySpuId(spuId);
model.addAllAttributes(attributeMap);

// 生成静态页面
goodsService.createGoodsHtml(spuId, attributeMap);
// 返回页面视图
return "goods";
}
  • 配置nginx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  server {
listen 80;
server_name www.leyou.com;

# location映射规则, proxy_pass代理转发
location /goods {
# 先找本地
root html;
# 请求的文件不存在,就反向代理
if (!-f $request_filename) {
proxy_pass http://127.0.0.1:8084;
break;
}
proxy_connect_timeout 600;
proxy_read_timeout 600;
}
}

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×