freemarker
介紹
freemarker是apache的一個開源的模板引擎。
作用:freemarker模板引擎可以通過模板和數據生成靜態化頁面。
優點:
- 提前根據模板和數據生成靜態化頁面,通過io流,將頁面寫入到硬盤上,訪問時直接訪問,可以不用訪問數據庫,可以大大降低數據庫的高併發讀取性能,使數據庫訪問量降低
- 由於頁面是提前生成的,所以訪問速度快,客戶體驗好。
- 由於html不需要tomcat解析,瀏覽器可以直接訪問,所以給tomcat降低高併發訪問壓力。
使用場景:
- 新聞網站或新聞頁面通過freemarker提前生成
- 電商網站的商品詳情頁面
使用原則:頁面有固定的樣式,一次生成多次讀取,儘量少得改動數據
同類型技術:velocity,但被替代了
freemarker生成靜態化頁面:
-
頁面=模板+數據
-
模板:模板在freemarker中是以.ftl爲後綴名的文件,在模板中可以使用html標籤,css,js,圖片等靜態資源,模板中可以使用el表達式來獲取數據,但無法使用jstl來判斷和循環,所以模板引擎會有一套自己的標籤庫。
-
數據:數據一般存儲在關係型數據庫或redis或mongodb中獲取
原理
小例子
一、引入依賴
<dependencies>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>
</dependencies>
二、創建ftl模板
<html>
<head>
<meta charset="utf-8">
<title>Freemarker入門小DEMO </title>
</head>
<body>
<#--我只是一個註釋,我不會有任何輸出 -->
${name},你好。${message}
</body>
</html>
三、生成靜態頁面
- 創建模板引擎對象
- 加載模板所在目錄
- 加載模板
- 創建數據
- 創建io流,流中指定文件的輸出位置和文件名
- 生成頁面
- 關閉io流
public class TestFreemarker {
public static void main(String[] args) throws Exception {
//1.創建模板引擎對象
Configuration conf = new Configuration();
//2.加載模板所在目錄
conf.setDirectoryForTemplateLoading(new File("D:\\Program Files\\IDEA Projects\\freemarkerDemo\\src\\main\\resources\\ftl"));
//3.加載模板
Template template = conf.getTemplate("test.ftl");
//4.創建數據
Map<String,Object> dataMap = new HashMap<>();
dataMap.put("name","王五");
dataMap.put("message","你好!");
//5.創建io流,流中指定文件的輸出位置和文件名
Writer writer = new FileWriter(new File("D:\\Program Files\\IDEA Projects\\freemarkerDemo\\src\\main\\resources\\pages\\hello.html"));
//6.生成頁面
template.process(dataMap,writer);
//7.關閉io流
writer.close();;
}
}
四、生成的靜態頁面
<html>
<head>
<meta charset="utf-8">
<title>Freemarker入門小DEMO </title>
</head>
<body>
王五,你好。你好!
</body>
</html>
FTL指令
assigh指令
(1)定義簡單類型:
<#assign linkman="周先生">
聯繫人:${linkman}
(2)定義對象類型:
<#assign info={"mobile":"13301231212",'address':'北京市昌平區王府街'} >
電話:${info.mobile} 地址:${info.address}
效果
include指令
此指令用於模板文件的嵌套,相當於一個頁面引入另一個頁面
創建模板文件head.ftl
<h1>黑馬信息網</h1>
我們修改test.ftl,在模板文件中使用include指令引入剛纔我們建立的模板
<#include "head.ftl"/>
list
注意:${person_index}
可以取出索引
<#-- 模擬獲取List集合數據 -->
<#list personList as person>
集合索引:${person_index}
${person}
</#list>
生成頁面
public class TestFreemarker {
public static void main(String[] args) throws Exception {
//1.創建模板引擎對象
Configuration conf = new Configuration();
//2.加載模板所在目錄
conf.setDirectoryForTemplateLoading(new File("D:\\Program Files\\IDEA Projects\\freemarkerDemo\\src\\main\\resources\\ftl"));
//3.加載模板
Template template = conf.getTemplate("test.ftl");
//4.創建數據
Map<String,Object> dataMap = new HashMap<>();
dataMap.put("name","王五");
dataMap.put("message","你好!");
/**
* 模擬List集合數據
*/
List<String> personList = new ArrayList<>();
personList.add("王五");
personList.add("張三");
personList.add("老劉");
personList.add("老七");
dataMap.put("personList",personList);
//5.創建io流,流中指定文件的輸出位置和文件名
Writer writer = new FileWriter(new File("D:\\Program Files\\IDEA Projects\\freemarkerDemo\\src\\main\\resources\\pages\\hello.html"));
//6.生成頁面
template.process(dataMap,writer);
//7.關閉io流
writer.close();;
}
}
生成的頁面
<html>
<head>
<meta charset="utf-8">
<title>Freemarker入門小DEMO </title>
</head>
<body>
王五,你好。你好!
集合索引:0
王五
集合索引:1
張三
集合索引:2
老劉
集合索引:3
老七
</body>
</html>
map
也是使用list指令來取
<#--模擬Map集合-->
<#list personMap?keys as key>
key:${key}
value:${personMap[key]}
</#list>
結果
<html>
<head>
<meta charset="utf-8">
<title>Freemarker入門小DEMO </title>
</head>
<body>
王五,你好。你好!
集合索引:0
王五
集合索引:1
張三
集合索引:2
老劉
集合索引:3
老七
key:001
value:王五
key:002
value:王四
key:003
value:王三
key:004
value:王二
</body>
</html>
判斷
<#-- 模擬獲取List集合數據 -->
<#list personList as person>
<#if person_index == 0>
第一次循環
<#else>
第${person_index+1}循環
</#if>
集合索引:${person_index}
${person}
</#list>
結果
<html>
<head>
<meta charset="utf-8">
<title>Freemarker入門小DEMO </title>
</head>
<body>
王五,你好。你好!
第一次循環
集合索引:0
王五
第2循環
集合索引:1
張三
第3循環
集合索引:2
老劉
第4循環
集合索引:3
老七
key:001
value:王五
key:002
value:王四
key:003
value:王三
key:004
value:王二
</body>
</html>
內建函數和運算符
內建函數語法格式: 變量+?+函數名稱
獲取集合大小
共 ${goodsList?size} 條記錄
日期格式化
代碼中對變量賦值:
map.put("today", new Date());
在模板文件中加入
當前日期:${today?date} <br>
當前時間:${today?time} <br>
當前日期+時間:${today?datetime} <br>
日期格式化: ${today?string("yyyy年MM月")}
數字轉換爲字符串
代碼中對變量賦值:
map.put("point", 102920122);
如果不轉化:每三位加一個逗號
累計積分:${point}
進行轉化:原樣顯示
累計積分:${point?c}
空值處理運算符
用法爲:variable??
如果該變量存在,返回true,否則返回false
<#if aaa??>
aaa變量存在
<#else>
aaa變量不存在
</#if>
缺失變量默認值:“!”
如果不存在展示後面的東西,如果存在打印值
${aaa!'這個變量不存在'}
運算符
和java中相同,有一個不同
區別
=或者==:判斷兩個值是否相等.