爲什麼要頁面靜態化
網頁靜態化解決方案在實際開發中運用比較多,例如新聞網站,門戶網站中的新聞頻道或者是文章類的頻道。比如CSDN有非常多的人在上面寫博客。一個博客的內容在發佈後很少變動。那麼這種場景下就適合使用頁面靜態化技術。在不請求數據庫的情況下架就能返回博客內容頁面:
對於電商網站的商品詳細頁來說,至少幾百萬個商品,每個商品又有大量的信息,這樣的情況同樣也適用於使用網頁靜態化來解決。
網頁靜態化技術和緩存技術的共同點都是爲了減輕數據庫的訪問壓力,但是具體的應用場景不同,緩存比較適合小規模的數據,而網頁靜態化比較適合大規模且相對變化不太頻繁的數據。另外網頁靜態化還有利於SEO。
另外我們如果將網頁以純靜態化的形式展現,就可以使用Nginx這樣的高性能的web服務器來部署。Nginx可以承載5萬的併發,而Tomcat只有幾百。
Freemarker 簡介
FreeMarker是一款用java語言編寫的模版引擎,它雖然不是web應用框架,但它很合適作爲web應用框架的一個組件。
特點:
- 輕量級模版引擎,不需要Servlet環境就可以很輕鬆的嵌入到應用程序中
- 能生成各種文本,如html,xml,java,等
- 入門簡單,它是用java編寫的,很多語法和java相似
工作原理:
Freemarker入門知識
Test.ftl
下面是一個Freemarker的模板。那麼我寫了常用的基礎語法。我們可以使用這個模板生成我們想要的靜態 html 頁面
<#--我只是一個註釋,我不會有任何輸出 -->
${name},你好。${message}
<h3>assigne指令</h3>
<#assign linkman="周先生">
聯繫人:${linkman}
<#assign info={"mobile":"13301231212",'address':'北京市昌平區王府街'} >
電話:${info.mobile} 地址:${info.address}
<h3>if指令</h3>
<#if success=true>
你已通過實名認證
<#else>
你未通過實名認證
</#if>
<h3>list指令</h3>
----商品價格表----<br>
<#list goodsList as goods>
${goods_index+1} 商品名稱: ${goods.name} 價格:${goods.price}<br>
</#list>
<h3>內建函數</h3>
<h4>獲取集合大小</h4>
共 ${goodsList?size} 條記錄
<h4>轉換JSON字符串爲對象</h4>
<#assign text="{'bank':'工商銀行','account':'10101920201920212'}" />
<#assign data=text?eval />
開戶行:${data.bank} 賬號:${data.account}
<h4>日期格式化</h4>
當前日期:${today?date} <br>
當前時間:${today?time} <br>
當前日期+時間:${today?datetime} <br>
日期格式化: ${today?string("yyyy年MM月")}
<h4>數字轉換爲字符串</h4>
累計積分:${point}
累計積分:${point?c}
<h3>空值處理運算符</h3>
<h4>判斷某變量是否存在:“??”</h4>
<#if aaa??>
aaa變量存在
<#else>
aaa變量不存在
</#if>
<h4>缺失變量默認值:“!”</h4>
${aaa!'-'}
<h3>運算符</h3>
<h4>算數運算符</h4>
FreeMarker表達式中完全支持算術運算,FreeMarker支持的算術運算符包括:+, - , * , / , %
<h4>邏輯運算符</h4>
邏輯運算符有如下幾個:
邏輯與:&&
邏輯或:||
邏輯非:!
邏輯運算符只能作用於布爾值,否則將產生錯誤
<h4>比較運算符</h4>
表達式中支持的比較運算符有如下幾個:
1 =或者==:判斷兩個值是否相等.
2 !=:判斷兩個值是否不等.
3 >或者gt:判斷左邊值是否大於右邊值
4 >=或者gte:判斷左邊值是否大於等於右邊值
5 <或者lt:判斷左邊值是否小於右邊值
6 <=或者lte:判斷左邊值是否小於等於右邊值
注意: =和!=可以用於字符串,數值和日期來比較是否相等,但=和!=兩邊必須是相同類型的值,否則會產生錯誤,而且FreeMarker是精確比較,"x","x ","X"是不等的.其它的運行符可以作用於數字和日期,但不能作用於字符串,大部分的時候,使用gt等字母運算符代替>會有更好的效果,因爲 FreeMarker會把>解釋成FTL標籤的結束字符,當然,也可以使用括號來避免這種情況,
後臺類
package com.cpc.freemarker;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
public class Demo001 {
public static void main(String[] args) throws IOException, TemplateException {
// 1.創建配置類
Configuration configuration = new Configuration(Configuration.getVersion());
// 2.設置模板所在的目錄
configuration.setDirectoryForTemplateLoading(
new File("D:\\code\\code_eclipse\\臨時項目\\cpc_lunece_freemarker\\src\\main\\resources"));
// 3.設置字符集
configuration.setDefaultEncoding("utf-8");
// 4.加載模板
Template template = configuration.getTemplate("test.ftl");
// 5.創建數據模型
Map map = new HashMap();
map.put("name", "cpc");
map.put("message", "歡迎來到神奇的博客網站:http://www.cpc.com!");
map.put("success", true);
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);
map.put("today", new Date());
map.put("point", 102920122);
// 6.創建Writer對象
Writer out = new FileWriter(new File("D:\\code\\code_eclipse\\臨時項目\\cpc_lunece_freemarker\\src\\main\\webapp\\freemarker\\test.html"));
// 7.輸出
template.process(map, out);
// 8.關閉Writer對象
out.close();
}
}
結果圖
將網頁靜態化用於博客網站
blogDetail.ftl
<div class="data_list">
<div class="data_list_title">
<img src="../blog_show_icon.png"/>
博客信息
</div>
<div>
<div class="blog_title"><h3><strong>${blog.title }</strong></h3></div>
<div class="blog_share">
<!-- <div class="bshare-custom"><a title="分享到QQ空間" class="bshare-qzone"></a><a title="分享到新浪微博" class="bshare-sinaminiblog"></a><a title="分享到人人網" class="bshare-renren"></a><a title="分享到騰訊微博" class="bshare-qqmb"></a><a title="分享到網易微博" class="bshare-neteasemb"></a><a title="更多平臺" class="bshare-more bshare-more-icon more-style-addthis"></a><span class="BSHARE_COUNT bshare-share-count">0</span></div><script type="text/javascript" charset="utf-8" src="http://static.bshare.cn/b/buttonLite.js#style=-1&uuid=&pophcol=2&lang=zh"></script><script type="text/javascript" charset="utf-8" src="http://static.bshare.cn/b/bshareC0.js"></script> -->
</div>
<div class="blog_info">
發佈時間:『${blog.releaseDate?datetime }』 博客類別:${blog.btid } 閱讀(${blog.clickHit })
</div>
<div class="blog_content">
${blog.content }
</div>
</div>
</div>
後臺代碼:
package com.cpc.freemarker;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import com.cpc.blog.util.DBAccess;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
public class Demo002 {
@SuppressWarnings("rawtypes")
public static void main(String[] args) throws IOException, TemplateException, SQLException {
// 1.創建配置類
Configuration configuration = new Configuration(Configuration.getVersion());
// 2.設置模板所在的目錄
configuration.setDirectoryForTemplateLoading(
new File("D:\\code\\code_eclipse\\臨時項目\\cpc_lunece_freemarker\\src\\main\\webapp\\freemarker"));
// 3.設置字符集
configuration.setDefaultEncoding("utf-8");
// 4.加載模板 (這是在 剛剛設置好的 目錄下面去找)
Template template = configuration.getTemplate("blogDetail.ftl");
createPage(template);
}
private static void createPage(Template template) throws SQLException, IOException, TemplateException {
Connection con = DBAccess.getConnection();
String sql = "select * from t_lucene_freemarker_blog";
PreparedStatement pst = con.prepareStatement(sql);
ResultSet rs = pst.executeQuery();
Map map = new HashMap<>();
Map<String, Object> blog = new HashMap<>();
while(rs.next()) {
blog.put("bid", rs.getObject("bid"));
blog.put("title", rs.getObject("title"));
blog.put("releaseDate", rs.getObject("releaseDate"));
blog.put("btid", rs.getObject("btid"));
blog.put("clickHit", rs.getObject("clickHit"));
blog.put("content", rs.getObject("content"));
map.put("blog", blog);
// // 6.創建Writer對象
Writer out = new FileWriter(new File("D:\\code\\code_eclipse\\臨時項目\\cpc_lunece_freemarker\\src\\main\\webapp\\freemarker\\"+blog.get("bid")+".html"));
// 7.輸出
template.process(map, out);
// 8.關閉Writer對象
out.close();
}
DBAccess.close(con, pst, rs);
}
}
其中的一個頁面: