網頁靜態化技術Freemarker
網頁靜態化解決方案在實際開發中運用比較多,例如新聞、電商網站等等。
對於電商網站的商品詳細頁來說,至少幾百萬個商品,每個商品又有大量的信息,這樣的情況同樣也適用於使用網頁靜態化來解決。
網頁靜態化技術和緩存技術的共同點都是爲了減輕數據庫的訪問壓力,但是具體的應用場景不同,緩存比較適合小規模的數據,而網頁靜態化比較適合大規模且相對變化不太頻繁的數據。另外網頁靜態化還有利於SEO。
另外我們如果將網頁以純靜態化的形式展現,就可以使用Nginx這樣的高性能的web服務器來部署。Nginx可以承載5萬的併發,而Tomcat只有幾百。關於Nginx在後續的博客中會詳細講解。
什麼是FreeMarker
FreeMarker 是一個用 Java 語言編寫的模板引擎,它基於模板來生成文本輸出。FreeMarker與 Web 容器無關,即在 Web 運行時,它並不知道 Servlet 或 HTTP。它不僅可以用作表現層的實現技術,而且還可以用於生成 XML,JSP 或 Java 等。
入門小Demo
- 引入依賴
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>
- 創建模板文件
模板文件中的四種元素:
1、文本,直接輸出的部分
2、註釋,即<#–…-->格式不會輸出
3、插值(Interpolation):即${…}部分,將使用數據模型中的部分替代輸出
4、FTL指令:FreeMarker指令,和HTML標記類似,名字前加#予以區分,不會輸出。
現在就開始創建一個簡單的模板文件test.ftl
<html>
<head>
<meta charset="utf-8">
<title>Freemarker入門小DEMO </title>
</head>
<body>
<#--我只是一個註釋,我不會有任何輸出 -->
${name},你好。${message}
</body>
</html>
- 生成文件
使用步驟:
第一步:創建一個 Configuration 對象,直接 new 一個對象。構造方法的參數就是 freemarker的版本號。
第二步:設置模板文件所在的路徑。
第三步:設置模板文件使用的字符集。一般就是 utf-8.
第四步:加載一個模板,創建一個模板對象。
第五步:創建一個模板使用的數據集,可以是 pojo 也可以是 map。一般是 Map。
第六步:創建一個 Writer 對象,一般創建一 FileWriter 對象,指定生成的文件名。
第七步:調用模板對象的 process 方法輸出文件。
第八步:關閉流
代碼:
創建Test類 main方法如下:
//1.創建配置類
Configuration configuration=new Configuration(Configuration.getVersion());
//2.設置模板所在的目錄
configuration.setDirectoryForTemplateLoading(new File("D:/work/freemarkerDemo/src/main/resources/"));
//3.設置字符集
configuration.setDefaultEncoding("utf-8");
//4.加載模板
Template template = configuration.getTemplate("test.ftl");
//5.創建數據模型
Map map=new HashMap();
map.put("name", "張三 ");
map.put("message", "歡迎來到神奇的品優購世界!");
//6.創建Writer對象
Writer out =new FileWriter(new File("d:\\test.html"));
//7.輸出
template.process(map, out);
//8.關閉Writer對象
out.close();
執行後,在D盤根目錄即可看到生成的test.html ,打開看看
FTL指令
- assign指令
此指令用於在頁面上定義一個變量
(1)定義一個簡單的類型:
<#assign linkman="周先生">
聯繫人:${linkman}
(2) 定義對象類型:
<#assign info={"mobile":"13301231212",'address':'北京市昌平區王府街'} >
電話:${info.mobile} 地址:${info.address}
- if 指令
<#if success=true>
你已通過實名認證
<#else>
你未通過實名認證
</#if>
在代碼中對str變量賦值
map.put("success", true);
在freemarker的判斷中,可以使用= 也可以使用==
- list 指令
實現以下效果:
代碼中對goodList賦值
List goodsList=new ArrayList();
Map goods1=new HashMap();
goods1.put("name", "蘋果");
goods1.put("price", 5.8);
Map goods2=new HashMap();
goods2.put("name", "香蕉");
goods2.put("price", 2.5);
Map goods3=new HashMap();
goods3.put("name", "橘子");
goods3.put("price", 3.2);
goodsList.add(goods1);
goodsList.add(goods2);
goodsList.add(goods3);
map.put("goodsList", goodsList);
在模板中添加
----商品價格表----<br>
<#list goodsList as goods>
${goods_index+1} 商品名稱: ${goods.name} 價格:${goods.price}<br>
</#list>
- 獲得集合大小
共 ${goodsList?size} 條記錄
- 轉換JSON字符串爲對象
<#assign text="{'bank':'工商銀行','account':'10101920201920212'}" />
<#assign data=text?eval />
開戶行:${data.bank} 賬號:${data.account}
- 日期格式化
代碼中賦值
map.put("today",new Date());
在模板中加入
當前日期:${today?date} <br>
當前時間:${today?time} <br>
當前日期+時間:${today?datetime} <br>
日期格式化: ${today?string("yyyy年MM月")}
- 數字轉字符串
修改代碼
map.put("point", 102920122);
修改模板
累計積分:${point}
- 判斷某變量是否存在:“??”
用法爲:variable??,如果該變量存在,返回true,否則返回false
<#if aaa??>
aaa變量存在
<#else>
aaa變量不存在
</#if>
- 缺失變量默認值:“!”
我們除了可以判斷是否爲空值,也可以使用!對null值做轉換處理
在模板文件中加入
${aaa!'-'}
在代碼中不對aaa賦值,也不會報錯了 ,當aaa爲null則返回!後邊的內容
- FreeMarker表達式中完全支持算術運算,FreeMarker支持的算術運算符包括:+, - , * , / , %
- 邏輯運算符
邏輯運算符有如下幾個:
邏輯與:&&
邏輯或:||
邏輯非:!
邏輯運算符只能作用於布爾值,否則將產生錯誤 - 比較運算符
表達式中支持的比較運算符有如下幾個:
1 =或者==:判斷兩個值是否相等.
2 !=:判斷兩個值是否不等.
3 >或者gt:判斷左邊值是否大於右邊值
4 >=或者gte:判斷左邊值是否大於等於右邊值
5 <或者lt:判斷左邊值是否小於右邊值
6 <=或者lte:判斷左邊值是否小於等於右邊值
注意 : =和!=可以用於字符串,數值和日期來比較是否相等,但=和!=兩邊必須是相同類型的值,否則會產生錯誤,而且FreeMarker是精確比較,“x”,"x ","X"是不等的.其它的運行符可以作用於數字和日期,但不能作用於字符串,大部分的時候,使用gt等字母運算符代替>會有更好的效果,因爲 FreeMarker會把>解釋成FTL標籤的結束字符,當然,也可以使用括號來避免這種情況,如:<#if (x>y)>