1. 程式人生 > >怎樣使用FreeMarker來實現動態網頁靜態化

怎樣使用FreeMarker來實現動態網頁靜態化

眾所周知,隨著網站的訪問量增加,如何給使用者以良好的訪問體驗就顯得尤為重要。提升網站效能便成為一些網站面臨的一大難題,像hao123這樣的導航網站要提升網站的效能只要部署的web伺服器數量足夠就可以承載超大規模的訪問量,如果是一個動態的網站呢?例如像鳳凰新聞、網易新聞這樣的CMS系統,淘寶、京東這樣的大型購物網站由於這些網站都使用到了資料庫這也就很難做到單純的通過增加web伺服器數量的方式來有效的提升網站的效能,但是這些網站並沒有出現或者說極少出現因為訪問量過大而造成頁面響應緩慢的問題。這其中有什麼樣的技術手段使得這些大型的動態網站能夠有如此高的效能呢?目前提升網站效能的方法通常有HTML靜態化、圖片伺服器分離、資料庫叢集、

負載均衡、程式碼優化、壓縮JS和CSS檔案等等。其中HTML靜態化的目的其實就是降低HTTP請求個數從而降低資料庫的操作從而達到提高網站執行速度,這也是一個最有效的提升網站效能的方法之一。本文將通過具體案例講解如何採用FreeMarker將動態網頁靜態化從而達到提升網站效能的目的。

一:FreeMarker簡介

1,動態網頁與靜態網頁的差距

2,FreeMarker的原理

3,FreeMarker特有表示式

4,FreeMarker常用的命令

1,動態網頁和靜態網頁差異?

1)靜態網頁:

  a、靜態網頁的內容穩定,頁面載入速度快。

  b、靜態網頁的沒有資料庫支援,在網站製作和維護方面的工作量較大。

  c、靜態網頁的互動性差,有很大的侷限性。

  2)動態網頁:

  a、互動性好。

  b、動態網頁的資訊都需要從資料庫中讀取,每開啟一個一面就需要去獲取一次資料庫,如果訪問人數很多,也就會對伺服器增加很大的荷載,從而影響這個網站的執行速度。

  通過上面的比較我們不難看出,要提升網站的效能,我們只要把動態網頁做成靜態網頁就會在執行速度方面有顯著的提升,但是問題出來了,如果將所有頁面都做成靜態頁面顯然是不切實際的。有什麼辦法能讓我們的網站即能有動態網頁的互動性,又有靜態網頁的載入速度呢?FreeMarker便能實現這樣的需求:實現動態網頁靜態化。


2、FreeMarker原理

  FreeMarker是一個基於Java的開發包和類庫的一種將模板和資料進行整合並輸出文字的通用工具,FreeMarker實現頁面靜態化的原理是:將頁面中所需要的樣式寫入到FreeMarker模板檔案中,然後將頁面所需要的資料進行動態繫結並放入到Map中,然後通過FreeMarker的模板解析類process()方法完成靜態頁面的生成。其工作原理如下圖所示。

3、FreeMarker表示式

  表示式可以說是FreeMarker的核心功能,表示式放置在插值語法“${...}”之中時,表面需要輸出表達式的值,表示式語法也可以與FreeMarker標籤結合,用於控制輸出。

  1)直接指定值

  例如:${“zhangsan”}

  2)輸出變數值

  FreeMarker的表示式輸出變數時,這些變數可以是頂層變數,也可以是Map物件中的變數,還可以是集合中的變數,並可以使用點(.)語法來訪問Java物件的屬性,例如:${user.name}。

  3)字串操作

  a、字串的連線,字串的連線可以直接使用雲算符“+”來連線字串也可以使用${..}(或#{..})在字串常量部分插入表示式的值,從而完成字串連線。

  b、字串的擷取,${book[1..4]}

  4)集合連線運算子,這裡所說的集合連線運算是將兩個集合連線成一個新的集合,連線集合的運算子是“+”,例如:

 5)Map連線運算子Map物件的連線運算也是將兩個Map物件連線成一個新的Map物件,Map物件的連線運算子是+。如果兩個Map物件具有相同的 key,則後加入Map裡的key所對應的value替代原來key所對應的value

Map物件使用花括號包括,Map中的key-value對之間以英文冒號":"分隔,多組key-value對之間以英文逗號","分隔.下面是一個例子: 
{"語文":78, "數學":80} 
Map物件的key和value都是表示式,但是key必須是字串 


6)算術運算子,FreeMarker表示式中完全支援算術運算。FreeMarker支援的算術運算子包括: +,-,*,/,%

7)比較運算子,FreeMarker表示式中支援的比較運算子有如下幾個

  a、=(或者==):判斷兩個值是否相等.

  b、!=:判斷兩個值是否不相等

  c、 >(或者gt):判斷座標值是否大於右邊值

  d、 >=(或者gte):判斷座標值是否大於等於右邊值

  e、 <(或者lt):判斷左邊值是否小於右邊值

  f、 <=(或者lte):判斷左邊值是否小於等於右邊值

8)邏輯運算子,FreeMarker中的邏輯運算子有如下幾個:

  a、邏輯與:&&

  b、邏輯或:||

  c、邏輯非:!

  9)內建函式

  FreeMarker提供了一些內建函式用來轉換輸出,可以在任何變數後緊跟?,?後緊跟內建函式,就可以通過內建函式來轉換輸出變數,例如:${test?upper_case?html}這裡就是將test字串轉換為大寫並進行HTML編碼。

html:對字串進行HTML編碼 
cap_first:使字串第一個字母大寫 
lower_case:將字串轉換成小寫 
upper_case:將字串轉換成大寫 
trim:去掉字串前後的空白字元 

下面是集合的常用內建函式 
size:獲取序列中元素的個數 

下面是數字值的常用內建函式 
int:取得數字的整數部分,結果帶符號 
例如: 
<#assign test="Tom & Jerry"> 
${test?html} 
${test?upper_case?html} 
結果是:Tom &amp; Jerry   TOM &amp; JERRY 

  10)空值處理運算子

  FreeMarker對空值的處理非常嚴格,FreeMarker的變數必須有值,如果存在沒有賦值的變數就會丟擲異常,為了處理缺失變數FreeMarker提供了兩個運算子:“!”和“??”,其中“!”用於指定缺失變數的預設值,“??”用來判斷某個變數是否存在。

4、FreeMarker的常用指令

1)if指令

  使用if指令可以有條件的跳過模板的一部分,和程式語言中的if相似,例如你想顯示某個使用者是否成年可以這樣寫:


2)switch、case、default、break指令

FreeMarker中使用switch、case、default、break指令和常用的程式設計語言中的一樣。例如:

  

雖然FreeMarker提供了switch指令,但它並不推薦使用switch指令來控制也輸出,而是推薦使用FreeMarker的if..elseif..else 指令來替代它。

3)list, break指令 

list指令是一個迭代輸出指令,用於迭代輸出資料模型中的集合,list指令的語法格式如下: 
<#list sequence as item> 
... 
</#list> 
上面的語法格式中,sequence就是一個集合物件,也可以是一個表示式,但該表示式將返回一個集合物件,而item是一個任意的名字,就是被迭代輸出的集合元素.此外,迭代集合物件時,還包含兩個特殊的迴圈變數: 
item_index:當前變數的索引值 
item_has_next:是否存在下一個物件 
也可以使用<#break>指令跳出迭代 

  當在HTML中需要用列表遍歷集合的內容時,list就顯得尤為重要,例如當我們需要遍歷一個使用者集合時可以這樣寫:


4)include 指令

include指令的作用類似於JSP的包含指令,用於包含指定頁,include指令的語法格式如下:

  <#include filename [options]>

  在上面的語法格式中,兩個引數的解釋如下

  a)filename:該引數指定被包含的模板檔案

  b)options:該引數可以省略,指定包含時的選項,包含encoding和parse兩個選項,encoding指定包含頁面時所使用的解碼集,而parse指定被包含是否作為FTL檔案來解析。如果省略了parse選項值,則該選項值預設是true。

5)assign指令

  通過assign(賦值)指令可以建立一個變數,或替換一個已存在的變數,例如:

  <#assign name=”zhangsan”>

三、FreeMarker實現網頁靜態化

  上面我簡單介紹了FreeMarker的基本用法,下面我將以具體例子採用Freemarker實現網頁靜態化的功能。

  1)新建一個Maven專案,在pom.xml檔案中新增FreeMarker的jar包,<version>2.3.20</version>

2)新建FreemarkerUtil工具類,其中包含了通過標準輸出流輸出模板的結果的方法和輸出到檔案中的方法。Freemarker是通過template.Configuration這個物件對模板進行載入的(它也處理建立和快取預解析模板的工作),然後我們通過getTemplate方法獲得你想要的模板,有一點要記住template.Configuration在你整個應用必須保證唯一例項。



3)新建User實體類,使用者屬性包含使用者主鍵、使用者年齡、郵箱,該實體類用於模擬從資料庫中查詢出資料。

4)新建模板檔案01.ftl,通過上面的介紹知道FreeMarker是一種基於模板的、用來生成輸出文字的通用工具,所以我們必須要定製符合自己業務的模板出來,然後將需要動態載入的資料通過FreeMarker的語法規範書寫生成靜態HTML的模板檔案,具體的語法規範在上前面已經詳細介紹。


5)新建Junit測試類TestFreemarker,用假資料模擬從資料庫中查詢資料並通過FreeMarker將模板檔案和資料結合生成靜態的HTML檔案。


 6) 通過以上步驟便成功的完成了一個通過FreeMarker生成靜態HTML檔案,生成的HTML檔案內容如圖3-1所示。


通過以上步驟便成功的實現了對一個需要從資料庫中查詢資料的動態頁面的靜態化處理,當我們每次更新了資料庫中的相應資訊以後,我們便可以重新執行這個方法,將這個頁面重新靜態化,當我們每次訪問這個網頁的時候便不會每一次都去資料庫中查詢資料了,而是訪問的一個已經一次性生成了的靜態頁面,這也就達到了提高網站執行速度的目標。

  四.總結

  一個大型的網站,比如入口網站,在提高網站效能時,基本的解決方案都是將HTML靜態化、圖片伺服器分離、資料庫叢集、負載均衡等幾個方案。其中HTML靜態化便大大降低了大量的資料庫訪問請求,在提高使用者訪問速度方面有很明顯的作用,大家都知道,效率最高、消耗最小的就是純靜態化的HTML頁面,所以我們儘可能使我們的網站上的頁面採用靜態頁面來實現,這個最簡單的方法其實也是最有效的解決方法。但是對於大量內容並且更新頻繁的網站,我們無法全部手動的去一個一個實現,於是便出現了像FreeMarker這樣的一些技術,在所有采用網頁靜態化手段的網站中,FreeMarker使用的比例大大的超過了其他的一些技術,由此可見FreeMarker在這方面的一些顯著優勢。

  對於一些門戶和資訊釋出型別的網站在互動性方面要求很高,對於這些網站來說盡可能的實現網頁靜態化是提高效能的必要手段,將系統的首頁、文章、社群帖子進行實時的靜態化、有更新的時候再重新靜態化也是大量使用的策略,像Mop大雜燴、網易新聞、鳳凰新聞等大型網站也都使用了這樣的策略。同時,HTML靜態化也是某些快取策略使用的手段,對於系統中頻繁使用資料庫查詢但是內容更新很小的應用,可以考慮使用FreeMarker將HTML靜態化。比如一些網站的公用設定資訊,這些資訊基本都是可以通過後臺來管理並存儲在資料庫中,這些資訊其實會大量的被前臺程式呼叫,每一次呼叫都會去查詢一次資料庫,但是這些資訊的更新頻率又會很小,因此也可以考慮將這部分內容進行後臺更新的時候進行靜態化,這樣就避免了大量的資料庫訪問請求,從而也就提高了網站的效能。