1. 程式人生 > >通用大型網站頁面靜態化解決方案

通用大型網站頁面靜態化解決方案

  最近自己做了一個做網路廣告的網站叫全方位商機平臺的專案,由於網站首頁上板塊劃分很多,不同板塊的資料庫查詢方式不同,首頁內容量巨大,如果按照一般的動態jsp頁面的話那麼資料庫查詢將是巨大的開銷,會導致首頁訪問速度的下降。於是考慮將這個首頁全部靜態化。
   整個網站才用struts2 + spring + hibernate + freemarker + urlrewrite完成。首頁純靜態化,頻道及其他頁面通過urlrewrite偽靜態。現在廢話少說。我先給出首頁jsp body原始碼:
Java程式碼
<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>

<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程式碼
       /**
* 生成靜態頁面主方法
* @param context ServletContext
* @param data 一個Map的資料結果集
* @param templatePath ftl模版路徑
* @param targetHtmlPath 生成靜態頁面的路徑
*/
ublic 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(); 


         /**
  * 生成靜態頁面主方法
  * @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程式碼
       /**
* 生成友情連結的靜態頁index_link.html
* @param context
* @param data
*/
ublic static void createIndexFriendLink(ServletContext context,Map<String,Object> data){ 
crateHTML(context,data,”index_link.ftl”,”index_link.html”); 

         /**
  * 生成友情連結的靜態頁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程式碼
        /**
* 生成友情連結靜態頁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”; 
    } 
}

         /**
  * 生成友情連結靜態頁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程式碼
<#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>

<#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方法實時的生成靜態頁面。如果更新速度不慢可以在後臺手動更新或者利用作業系統的定時任務功能去執行你的靜態頁面生成程式。