1.什么是静态化
静态化就是我们把Thymeleaf渲染后的页面转变成静态页面,并且保存起来,用户每次访问的都是已经存在的静态页,数据库的查询压力也就小了,就比如商品详情页,只要商品的信息没有改变,无论是哪个用户查询的结果都是一样的,所以商品的详情页,完全可以静态化,事实上电商网站也是这样做的
2.如何实现静态化
目前,静态化页面都是通过模板引擎来生成,而后保存到nginx服务器来部署。常用的模板引擎比如:
-
Freemarker
-
Velocity
-
Thymeleaf
我们之前就使用的Thymeleaf,来渲染html返回给用户。Thymeleaf除了可以把渲染结果写入Response,也可以写到本地文件,从而实现静态化。
前后端的交互顺序
- 前端提交请求
- 请求被控制层收到,最终调用持久层查库,把数据放入model
- Thymeleaf把model里面的数据渲染到模板视图里面XXX.html
- 把渲染后的全部信息,全部写入到response里面
既然能写到response里面,就能写入到其他路径下**。
Thymeleaf如何把信息写入到其他路径下?
ThymeleafAutoConfiguration里面的TemplateEngine模板引擎使用下面的方法process(String template, IContext context, Writer writer)
3.几个重要的概念
- context:上下文
这是用来保存模型数据,当模板引擎渲染时,可以从Context上下文中 获取数据用于渲染。当与SpringBoot结合使用时,我们放入Model的数据就会被处理到Context,作为模板渲染的数据使用。 - TemplateResolver:模板解析器
- 用来读取模板相关的配置,例如:模板存放的位置信息,模板文件名称,模板文件的类型等等。
- 当与SpringBoot结合时,TemplateResolver已经由其创建完成,并且各种配置也都有默认值,比如模板存放位置,其默认值就是:templates。比如模板文件类型,其默认值就是html。
- TemplateEnginee:模板引擎
用来解析模板的引擎,需要使用到上下文、模板解析器。分别从两者中获取模板中需要的数据,模板文件。然后利用内置的语法规则解析,从而输出解析后的文件。来看下模板引起进行处理的函数:
templateEngine.process(“模板名”, context, writer);- 模板名称
- 上下文:里面包含模型数据
- writer:输出目的地的流
输出时,我们可以指定输出的目的地,如果目的地是Response的流, 那就是网络响应。如果目的地是本地文件,那就实现静态化了。
而在SpringBoot中已经自动配置了模板引擎,因此我们不需要关心这个。现在我们做静态化,就是把输出的目的地改成本地文件即可!
4.实现静态化
1.导入thymeleaf启动器,使用thymeleaf引擎来实现静态化
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
2.准备要静态化的模板(classpath:templates文件夹下)
person.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>静态化模板</title>
</head>
<body>
<h1 th:text="${person.id}"></h1>
<h1 th:text="${person.username}"></h1>
<h1 th:text="${person.age}"></h1>
</body>
</html>
3.编写实现静态化的Service
personService.java
package com.ty.service;
import com.ty.entity.Person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
@Service
public class PersonService {
private final static String DESC_PATH = "d:/person/";
@Autowired
TemplateEngine templateEngine;
public void createHtml(int id){
//创建上下文
Context context = new Context();
Person person = loadPerson(id);
//上下文放入数据
context.setVariable("person",person);
//路径的判断,没有自动创建
File file0 = new File(DESC_PATH);
if (!file0.exists()){
file0.mkdirs();
}
//定义本地保存的静态文件名
File file = new File(DESC_PATH+id+".html");
if(file.exists()){
file.delete();
}
try {
//定义一个打印流
PrintWriter pw = new PrintWriter(file);
templateEngine.process("person",context,pw);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
//模拟封装数据的方法
public Person loadPerson(int id){
Person p = new Person();
p.setUsername("李子柒");
p.setAge(18);
p.setId(id);
return p;
}
}
4.进行测试
package com.ty;
import com.ty.service.PersonService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class ThymeleafFirstApplicationTests {
@Autowired
PersonService personService;
@Test
void contextLoads() {
personService.createHtml(88088);
}
}