Freemarker網站靜態化的實現

  做程序也做了將近4年時間了,從來沒有發過什麼技術性的文章,今天發一個只在大家一起共同學習進步,如有錯誤地方請指正。
  最近自己做了一個做網絡廣告的網站叫全方位商機平臺的項目,由於網站首頁上板塊劃分很多,不同板塊的數據庫查詢方式不同,首頁內容量巨大,如果按照一般的動態jsp頁面的話那麼數據庫查詢將是巨大的開銷,會導致首頁訪問速度的下降。於是考慮將這個首頁全部靜態化。參考地址:http://www.31pt.com/。首頁的速度是非常快的。
  整個網站才用struts2 + spring + hibernate + freemarker + urlrewrite完成。首頁純靜態化,頻道及其他頁面通過urlrewrite僞靜態。現在廢話少說。我先給出首頁jsp body源代碼:

Java code
<body> <div id="wrap"> <!--頭部開始--> <jsp:include page="/html/top.html" flush="true"></jsp:include> <!--頭部結束--> <!--導航開始--> <jsp:include page="/html/channel.html" flush="true"></jsp:include> <!--導航結束--> <jsp:include page="/html/center.html" flush="true"></jsp:include> <!--友情連接開始--> <jsp:include page="/html/index_link.html" flush="true"></jsp:include> <!--友情結束--> <!--底部開始--> <jsp:include page="/html/bottom.html" flush="true"></jsp:include> <!--底部結束--> </div> </body>


整個網站首頁的基本結構是通過jsp的include標籤將所有通過freemarker生成的靜態頁面組織起來。後臺控制各個部分的靜態頁生成。這樣做將首頁進行了拆分,便於了靜態頁面的維護,當我們需要生成“友情鏈接”部分的時候就只生成友情鏈接部分,而不需要將整個頁面都從新生成一次。
  以下是我生成靜態頁最核心的方法,使用freemarker。

Java code
/** * 生成靜態頁面主方法 * @param context ServletContext * @param data 一個Map的數據結果集 * @param templatePath ftl模版路徑 * @param targetHtmlPath 生成靜態頁面的路徑 */ public static void crateHTML(ServletContext context,Map<String,Object> data,String templatePath,String targetHtmlPath){ Configuration freemarkerCfg = new Configuration(); //加載模版 freemarkerCfg.setServletContextForTemplateLoading(context, "/"); freemarkerCfg.setEncoding(Locale.getDefault(), "UTF-8"); try { //指定模版路徑 Template template = freemarkerCfg.getTemplate(templatePath,"UTF-8"); template.setEncoding("UTF-8"); //靜態頁面路徑 String htmlPath = context.getRealPath("/html")+"/"+targetHtmlPath; File htmlFile = new File(htmlPath); Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(htmlFile), "UTF-8")); //處理模版 template.process(data, out); out.flush(); out.close(); } catch (Exception e) { e.printStackTrace(); } }


其實很簡單,只要Google一下就有很多這方面的代碼。我也是Google的代碼然後自己再根據實際情況修改。簡單說明一下參數:
ServletContext :這個不用說了吧。做java web的應該都知道,只不過struts2中這樣獲取ServletActionContext.getServletContext()
Map <String,Object> data : 模版的數據來源。freemarker通過一個Map給ftl模版送數據。
現在已友情鏈接爲列子詳細介紹靜態頁面如何生成。其他模塊以此類推。
String templatePath : ftl所在的路徑。我這裏相對於網站的一個相對路徑然後通過ServerContext獲取絕對路徑。
String targetHtmlPath : 最後生成靜態頁的路徑:我這裏相對於網站的一個相對路徑然後通過ServerContext獲取絕對路徑。

友情鏈接根據這段代碼 <jsp:include page="/html/index_link.html" flush="true"> </jsp:include>我們需要freemarker生成一個index_link.html文件。友情鏈接數據來源通過數據庫查詢獲取。
然後再寫一個方法專門生成友情鏈接靜態頁面:

Java code
/** * 生成友情鏈接的靜態頁index_link.html * @param context * @param data */ public static void createIndexFriendLink(ServletContext context,Map<String,Object> data){ crateHTML(context,data,"index_link.ftl","index_link.html"); }


此方法調用上面的createHTML方法。
然後根據以上方法我們就可以再Struts2的action裏面從數據庫查詢數據放入map調用createIndexFriendLink()方法生成靜態頁了。
這是action中的一個方法:

Java code
/** * 生成友情鏈接靜態頁index_link.html * @return */ public String createLink(){ //權限驗證 if(! this.isAccess()) return "error"; try{ //得到友情鏈接 List links = friendLinkDAO.findAll(); //準備數據 HashMap<String,Object> data = new HashMap<String,Object>(); data.put("links", links); //調用靜態頁面方法 HTML.createIndexFriendLink(ServletActionContext.getServletContext(), data); addActionMessage("靜態頁面生成成功!"); return "message"; }catch(Exception e){ e.printStackTrace(); return "failure"; } }


List links = friendLinkDAO.findAll();通過spring注入action的hiberate DAO獲取數據給list然後通過以下代碼
HashMap <String,Object> data = new HashMap <String,Object>();
data.put("links", links);
準備數據調用createIndexFriendLink()方法。
以下是:ftl模版源碼:

Java code
<#if links?size != 0> <div class="link"> <strong>友情鏈接:</strong> <#list links as link> <a href="${link.linkUrl}" target="_blank" title="${link.linkName}">${link.linkName}</a> </#list> </div> <#else> <div class="link"></div> </#if>


這樣友情鏈接靜態頁就生成了。然後其他靜態頁依此葫蘆畫瓢。

總結:雖然靜態頁訪問速度快和其他的好處,但實現起來畢竟還是很麻煩了,維護也是一個麻煩事情。如果您的站點更新速度快那麼就需要在你的後臺數據更新部分調用相應的createHTML方法實時的生成靜態頁面。如果更新速度不慢可以在後臺手動更新或者利用操作系統的定時任務功能去執行你的靜態頁面生成程序。www.361pt.com這個網站我是才用了這兩種方式。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章