Skip to content

Commit 24fc12a

Browse files
authored
Create README.md
1 parent 6a96cb3 commit 24fc12a

File tree

1 file changed

+228
-0
lines changed

1 file changed

+228
-0
lines changed

springboot-thymeleaf-static/README.md

+228
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
## 什么是静态化
2+
3+
静态化是指把动态生成的HTML页面变为静态内容保存,以后用户的请求到来,直接访问静态页面,不再经过服务的渲染。
4+
5+
而静态的HTML页面可以部署在nginx中,从而大大提高并发能力,减小tomcat压力。
6+
7+
## 如何实现静态化
8+
9+
目前,静态化页面都是通过模板引擎来生成,而后保存到nginx服务器来部署。常用的模板引擎比如:
10+
11+
- Freemarker
12+
- Velocity
13+
- Thymeleaf
14+
15+
我们之前就使用的Thymeleaf,来渲染html返回给用户。Thymeleaf除了可以把渲染结果写入Response,也可以写到本地文件,从而实现静态化。
16+
17+
## Thymeleaf实现静态化
18+
19+
**概念**
20+
21+
先说下Thymeleaf中的几个概念:
22+
23+
- Context:运行上下文
24+
- TemplateResolver:模板解析器
25+
- TemplateEngine:模板引擎
26+
27+
> Context
28+
29+
上下文: 用来保存模型数据,当模板引擎渲染时,可以从Context上下文中获取数据用于渲染。
30+
31+
当与SpringBoot结合使用时,我们放入Model的数据就会被处理到Context,作为模板渲染的数据使用。
32+
33+
> TemplateResolver
34+
35+
模板解析器:用来读取模板相关的配置,例如:模板存放的位置信息,模板文件名称,模板文件的类型等等。
36+
37+
当与SpringBoot结合时,TemplateResolver已经由其创建完成,并且各种配置也都有默认值,比如模板存放位置,其默认值就是:templates。比如模板文件类型,其默认值就是html。
38+
39+
> TemplateEngine
40+
41+
模板引擎:用来解析模板的引擎,需要使用到上下文、模板解析器。分别从两者中获取模板中需要的数据,模板文件。然后利用内置的语法规则解析,从而输出解析后的文件。来看下模板引起进行处理的函数:
42+
43+
```java
44+
templateEngine.process("模板名", context, writer);
45+
```
46+
47+
三个参数:
48+
49+
- 模板名称
50+
- 上下文:里面包含模型数据
51+
- writer:输出目的地的流
52+
53+
在输出时,我们可以指定输出的目的地,如果目的地是Response的流,那就是网络响应。如果目的地是本地文件,那就实现静态化了。
54+
55+
而在SpringBoot中已经自动配置了模板引擎,因此我们不需要关心这个。现在我们做静态化,就是把输出的目的地改成本地文件即可!
56+
57+
## 具体实现步骤
58+
#### 相关依赖
59+
```xml
60+
<dependency>
61+
<groupId>org.springframework.boot</groupId>
62+
<artifactId>spring-boot-starter-thymeleaf</artifactId>
63+
</dependency>
64+
65+
<dependency>
66+
<groupId>org.projectlombok</groupId>
67+
<artifactId>lombok</artifactId>
68+
</dependency>
69+
```
70+
#### 准备静态原型
71+
`thymeleaf`文件夹下面新建一个`id.html`
72+
```html
73+
<!DOCTYPE html>
74+
<html lang="en" xmlns:th="http://www.thymeleaf.org">
75+
<head>
76+
<meta charset="UTF-8">
77+
<title>Thymeleaf 静态页面</title>
78+
</head>
79+
<body>
80+
<h1 th:text="'名字是:' + ${name}"></h1>
81+
<h1 th:text="'年龄是:' + ${age}"></h1>
82+
<h1 th:text="'邮箱是:' + ${email}"></h1>
83+
</body>
84+
</html>
85+
```
86+
#### 接口和实现类
87+
```java
88+
public interface ThymeleafService {
89+
90+
void createHtml(Long id);
91+
92+
void deleteHtml(Long id);
93+
}
94+
```
95+
实现类相关说明
96+
97+
定义一个存放静态文件的目录,这里你也可以写在`application.yml`文件中,再使用`@Value`注解也行。
98+
```java
99+
public static final String destPath = "D:/temp/static"; // 自己手动创建一个存在的文件路径
100+
```
101+
注入模板引擎`TemplateEngine`
102+
```java
103+
@Autowired
104+
private TemplateEngine templateEngine;
105+
```
106+
准备加载到页面上的数据,讲道理,这里加载的数据是根据id从数据库查询出来的,我这里就写固定了
107+
```java
108+
public Map<String, Object> loadModel(Long id) {
109+
Map<String, Object> map = new HashMap<>();
110+
map.put("name", "tellsea");
111+
map.put("age", 20);
112+
map.put("email", "3210054449@qq.com");
113+
return map;
114+
}
115+
```
116+
接下来就是重点,**创建静态页面的方法**
117+
```
118+
/**
119+
* 创建html页面
120+
*
121+
* @param id
122+
* @throws Exception
123+
*/
124+
public void createHtml(Long id) {
125+
// 上下文
126+
Context context = new Context();
127+
context.setVariables(loadModel(id));
128+
// 输出流
129+
File dest = new File(destPath, id + ".html");
130+
if (dest.exists()) {
131+
dest.delete();
132+
}
133+
try (PrintWriter writer = new PrintWriter(dest, "UTF-8")) {
134+
// 生成html,第一个参数是thymeleaf页面下的原型名称
135+
templateEngine.process("id", context, writer);
136+
} catch (Exception e) {
137+
log.error("[静态页服务]:生成静态页异常", e);
138+
}
139+
}
140+
```
141+
这里提供了一个删除静态页面的方法,做戏当然是做全套,删除的接口便于文章后面讲解实战运行
142+
```java
143+
@Override
144+
public void deleteHtml(Long id) {
145+
// 输出流
146+
File dest = new File(destPath, id + ".html");
147+
if (dest.exists()) {
148+
dest.delete();
149+
}
150+
}
151+
```
152+
#### 测试效果
153+
执行`createHtmlTest`测试类,然后查看`D:/temp/static`下生成的静态页面,Nice,直接双击生成的`Html`文件,浏览器就可以访问,效果为带数据的页面,Nice
154+
```java
155+
@RunWith(SpringRunner.class)
156+
@SpringBootTest
157+
public class ThymeleafServiceTest {
158+
159+
@Autowired
160+
private ThymeleafService thymeleafService;
161+
162+
@Test
163+
public void createHtmlTest() {
164+
thymeleafService.createHtml(1L);
165+
}
166+
}
167+
```
168+
169+
## 实战分析
170+
171+
上面的实现的功能我们这里把它理解为对于文章详情的静态页,方便下面说明
172+
173+
问题:什么时候调用创建、删除?
174+
175+
#### 新增、更新
176+
我们新增文章、更新文章,完成相应的操作数据库的业务逻辑之后,需要更新静态页面的数据,调用创建的接口,重新创建一个新的即可
177+
```java
178+
thymeleafService.createHtml(1L);
179+
```
180+
怎么覆盖?仔细看实现类的代码,**在创建页面之前,里面有写如果存在,则删除**
181+
```java
182+
if (dest.exists()) {
183+
dest.delete();
184+
}
185+
```
186+
187+
#### 删除
188+
删除数据库文章之后,直接删除静态页面即可
189+
```java
190+
pageService.deleteHtml(id);
191+
```
192+
193+
## 代理静态页面
194+
195+
我们修改`nginx`,让它对文章详情的请求进行监听,指向本地静态页面,如果本地没找到,才进行反向代理:
196+
```shell
197+
server {
198+
listen 80;
199+
server_name www.tellsea.com;
200+
201+
proxy_set_header X-Forwarded-Host $host;
202+
proxy_set_header X-Forwarded-Server $host;
203+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
204+
205+
location /item {
206+
# 先找本地
207+
root html; # 这里的html是root安装目录的html文件夹,可以自定义
208+
if (!-f $request_filename) { #请求的文件不存在,就反向代理
209+
proxy_pass http://127.0.0.1:8080;
210+
break;
211+
}
212+
}
213+
214+
location / {
215+
proxy_pass http://127.0.0.1:9002;
216+
proxy_connect_timeout 600;
217+
proxy_read_timeout 600;
218+
}
219+
}
220+
```
221+
222+
重启测试:
223+
224+
发现请求速度得到了极大提升,因为访问的是`HTML`的静态页面了。
225+
226+
## 相关链接
227+
- [示例源码:springboot-thymeleaf-static](https://github.com/Tellsea/springboot-learn/tree/master/springboot-thymeleaf-static "实例源码")
228+
- [Thymeleaf官方文档-Documentation](https://www.thymeleaf.org/documentation.html "Thymeleaf官方文档-Documentation")

0 commit comments

Comments
 (0)