哈喽,大家好,我是有勇气的牛排(全网同名)🐮🐮🐮
有问题的小伙伴欢迎在文末评论,点赞、收藏是对我最大的支持!!!。
前言
开发网站的时候,通常会对前后端技术进行选型,前后端分离项目不用多说,正如字面意思,分离开发即可。
但是有些项目需要做SEO优化,这就要使网页静态化,优化速度,提高网站在搜索引擎中的权重,尤其在百度是不支持js加载的页面场景中,页面静态化尤为重要,在Spring开发中,就可以使用模板引擎技术来支撑。
下面主要介绍:FreeMarker与thymeleaf 。
1 整合FreeMarker模板
FreeMark 官网: https://freemarker.apache.org
官方文档:https://freemarker.apache.org/docs/dgui_template_overallstructure.html
Apache FreeMark是一个模板引擎,一个基于模板和变化的数据生成文本输出(HTML网页、电子邮件、配置文件、源代码等)的Java库,模板是用FreeMark模板语言(FTL)编写的,这是一种简单的专用语言。
其逻辑为:
由java计算并提供数据,然后由FreeMark程序结果数据。
并且采用了 MVC (模型、视图、控制器)模式。

1.1 pom依赖引入
<!-- 模板引擎 引入freeMarker的依赖包. -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
1.2 yml配置
spring:http:encoding:force: true# 模版引擎编码为UTF-8charset: UTF-8# freemarker模板配置freemarker:allow-request-override: falsecache: falsecheck-template-location: truecharset: UTF-8content-type: text/html; charset=utf-8expose-request-attributes: falseexpose-session-attributes: falseexpose-spring-macro-helpers: false## 模版文件结尾.ftlsuffix: .ftl## 模版文件目录template-loader-path: classpath:/templates
1.3 后端
FreemarkController.java
/** @Author : 有勇气的牛排* @FileName: FreemarkController.java* desc : Freemark模板引擎* */package com.couragesteak.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Map;@Controller
public class FreemarkController {// import java.util.Map;// http://127.0.0.1:8080/freemarkIndex@RequestMapping("/freemarkIndex")public String freemarkIndex(Map<String, Object> result, HttpServletRequest request) {System.out.println(666);// 传数据到页面result.put("name", "有勇气的牛排");result.put("sex", "0");result.put("age", 20);ArrayList<Object> tagList = new ArrayList<>();tagList.add("全程");tagList.add("解决方案");result.put("tagList", tagList);return "freemarkIndex";}
}
1.4 前端
<div style="width: 200px;font-weight: 600;"><div style="border: 1px solid red">名字:${name}</div><div style="border: 1px solid red;margin-top: 10px;">性别:<#if sex=="0">男<#elseif sex=="1">女<#else>未知</#if></div><div style="border: 1px solid red;margin-top: 10px;">是否成年:<#if (age>=18)>成年<#else>未成年</#if></div><div style="border: 1px solid red;margin-top: 10px;">标签:<#list tagList as tag>${tag}</#list></div></div>

1.5 模板语法
1.5.1 变量表达式
名字:${name}
1.5.2 list
后端
// list
ArrayList<Object> tagList = new ArrayList<>();
tagList.add("全站");
tagList.add("解决方案");
result.put("tagList", tagList);
前端
<#break>: 跳出循环
<#list tagList as tag><p>${tag}</p><#break>
</#list>
1.5.3 if判断
两种方法
1 用符号代替: > gt , >= gte ,< lt , <= lte
2 加括号 <#if(x>y)>
<#if (age >= 18)><p>成年</p>
<#else><p>未成年</p>
</#if>
1.5.4 include
<#include "include.html"/>
<#include "/common/copyright.ftl" encoding="GBK" parse=false/>
1.5.5 switch
<span>4、switch</span>
<div><#switch 1><#case 3>第3页<#break><#case 1>第1页<#break><#case 2>第2页<#break></#switch>
</div>
2 整合 thymeleaf 渲染web页面
thymeleaf是一款用于渲染 xml/xhtml/xhtml5内容的模板引擎,类似于jsp、Velocity、FreeMaker等,它可以轻易的与Spring MVC等web框架进行集成作为 Web应用的模板引擎。
2.1 pom依赖
<!-- 模板引擎 引入thymeleaf的依赖-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
2.2 yml配置
spring:# ThymeLeaf配置thymeleaf:#prefix:指定模板所在的目录prefix: classpath:/templates/#check-tempate-location: 检查模板路径是否存在check-template-location: true#cache: 是否缓存,开发模式下设置为false,避免改了模板还要重启服务器,线上设置为true,可以提高性能。cache: truesuffix: .htmlencoding: UTF-8mode: HTML5
2.3 java后端
/** @Author : 有勇气的牛排* @FileName: ThymeleafController.java* desc :* */package com.couragesteak.controller;import com.couragesteak.entity.UserEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Map;@Controller
public class ThymeleafController {// http://127.0.0.1:8080/myThymeleaf@RequestMapping("/myThymeleaf")public String myThymeleafController(HttpServletRequest request, Map<String, Object> result) {
// request.setAttribute("ruser", new UserEntity("cs", 20));result.put("user", new UserEntity("cs", 17));ArrayList<Object> userEntitys = new ArrayList<>();userEntitys.add(new UserEntity("CS1", 16));userEntitys.add(new UserEntity("CS2", 20));result.put("userList", userEntitys);return "myThymeleaf";}
}
2.4 前端
位置:resources/templates
<div><table>姓名:<span th:text="${user.userName}"></span>年龄:<span th:text="${user.age}"></span></table><hr><div><ul th:each="user:${userList}"><li><span th:if="${user.age>= 18}">成年</span><span th:if="${user.age< 18}">未成年</span></li></ul></div></div>

2.5 前端模板语法
th:text: 设置当前元素的文本内容,相同功能的还有th:utext,两者的区别在于前者不会转义html标签,后者会。th:value: 设置当前元素的value值,类似修改指定html标签属性的还有th:src,th:href。th:each: 遍历循环元素,和th:text或th:value一起使用。注意该属性修饰的标签位置。th:if: 条件判断,类似的还有th:unless,th:switch,th:case。th:insert: 代码块引入,类似的还有th:replace,th:include,常用于公共代码块的提取复用。th:fragment: 定义代码块,方便被th:insert引用。th:object: 声明变量,一般和*{}一起配合使用。
th:attr : 修改任意属性,实际开发中用的较少,因为有丰富的其他th属性帮忙。
2.5.1 变量表达式 ${ }
<input type="text" th:value="${user.age}"><span>三目运算</span>
<input type="text" th:value="${user.age>=18?user.age:'未成年'}">
1 内置方法
一、strings:字符串格式化方法,常用的Java方法它都有。比如:equals,equalsIgnoreCase,length,trim,toUpperCase,toLowerCase,indexOf,substring,replace,startsWith,endsWith,contains,containsIgnoreCase等
二、numbers:数值格式化方法,常用的方法有:formatDecimal等
三、bools:布尔方法,常用的方法有:isTrue,isFalse等
四、arrays:数组方法,常用的方法有:toArray,length,isEmpty,contains,containsAll等
五、lists,sets:集合方法,常用的方法有:toList,size,isEmpty,contains,containsAll,sort等
六、maps:对象方法,常用的方法有:size,isEmpty,containsKey,containsValue等
七、dates:日期方法,常用的方法有:format,year,month,hour,createNow等
2 Map
java
Map myMap = new HashMap();
myMap.put("k1", "大哥");
myMap.put("k2", "牛");
result.put("myMap", myMap);
html
<span>7、Map</span>
<div th:if="${not #maps.isEmpty(myMap)}"><p th:text="${#maps.size(myMap)}"></p><p th:text="${#maps.containsKey(myMap,'k1')}"></p><p th:text="${#maps.containsValue(myMap,'K1')}"></p><p th:text="${myMap.k1}"></p><p></p>
</div>
3 迭代list
后端
ArrayList<Object> userEntitys = new ArrayList<>();
userEntitys.add(new UserEntity("CS1", 16));
userEntitys.add(new UserEntity("CS2", 20));
result.put("userList", userEntitys);
前端
<span>3、迭代list</span>
<div><ul th:each="user,i : ${userList}"><li th:text="${'序号'+(i['index']+1)+', 名字'+user.userName}"></li></ul>
</div>

4 date
java
result.put("NowDate", new Date());
html
<span>6、date</span>
<div><p>format : <span th:text="${#dates.format(NowDate)}"></span></p><p>custom format : <span th:text="${#dates.format(NowDate,'yyyy-MM-dd HH:mm:ss')}"></span></p><p>day : <span th:text="${#dates.day(NowDate)}"></span></p><p>month : <span th:text="${#dates.month(NowDate)}"></span></p><p>monthName : <span th:text="${#dates.monthName(NowDate)}"></span></p><p>year : <span th:text="${#dates.year(NowDate)}"></span></p><p>dayOfWeek : <span th:text="${#dates.dayOfWeek(NowDate)}"></span></p><p>dayOfWeekName : <span th:text="${#dates.dayOfWeekName(NowDate)}"></span></p><p>hour : <span th:text="${#dates.hour(NowDate)}"></span></p><p>minute : <span th:text="${#dates.minute(NowDate)}"></span></p><p>second : <span th:text="${#dates.second(NowDate)}"></span></p><p>createNow : <span th:text="${#dates.createNow()}"></span></p>
</div>
2.5.2 链接表达式 @{ }
使用此表达式,可以动态获取项目路径,改名等操作不影响。
修改配置文件项目路径
#修改项目名,链接表达式会自动修改路径,避免资源文件找不到
server:context-path=/emp
链接表达式
<div><script th:src="@{/js/login.js}"></script><script th:src="@{/js/login?k1=v1&k2=v2}"></script>
</div>
2.5.4 内容渲染标签
1 th:text 文本渲染
仅渲染文本
<span>1、文本渲染</span>
<p th:text="${user.userName}"></p>
2 dom渲染(代码常用)
<span>2、dom渲染</span>
<p th:utext="'<button>按钮</button>'+${user.userName}"></p>
2.5.5 script获取变量值
<span>5、script获取变量值</span>
<div><script th:inline="javascript">let userName = [[${user.userName}]];alert(userName);</script>
</div>
2.5.6 封装通用代码块 insert、replace、include
th:insert: 是在div中插入代码块。
th:replace: 代替当前div,与原html结构一致。
th:include: 直接引入代码,到当前。
路径:classpath:/templates/common
header.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><herder th:fragment="header"><div><h1>网页头部</h1></div>
</herder></body>
</html>
主页引用
index.html
<!-- 导入通用头部模板 -->
<div th:include="common/header::header"></div>
参考:
- 余胜军
- https://freemarker.apache.org/docs/dgui_template_overallstructure.html
- https://www.jianshu.com/p/5bbac20348ec
- https://www.couragesteak.com/article/288














