初識Freemarker

1.Freemarker定義

FreeMarker是一款模板引擎: 即一種基於模板和要改變的數據, 並用來生成輸出文本(HTML網頁、電子郵件、配置文件、源代碼等)的通用工具。 它不是面向最終用戶的,而是一個Java類庫,是一款程序員能夠嵌入他們所開發產品的組件。
FreeMarker是免費的,基於Apache許可證2.0版本發佈。其模板編寫爲FreeMarker Template Language(FTL),屬於簡單、專用的語言。須要準備數據在真實編程語言中來顯示,好比數據庫查詢和業務運算, 以後模板顯示已經準備好的數據。在模板中,主要用於如何展示數據, 而在模板以外注意於要展現什麼數據。html

最新版本FreeMarker 2.3.23。java

2.工做原理

  請看下面代碼:python

複製代碼
<html>
    <head>
        <title>Welcome!</title>
    </head>
    <body>
        <h1>Welcome ${user}!</h1>
        <p>Our latest product:
        <a href="${latestProduct.url}">${latestProduct.name}</a>!
    </body>
</html>
複製代碼

  模板文件保存在WEB服務器上,當有人訪問這個頁面時,Freemarker就會發出響應,動態轉換模板中${..}的部分,以後將結果發送到訪問者的web瀏覽器中,瀏覽器端看到的內容會是沒有Freemarker命令的頁面內容。程序員

  以上爲模板準備的數據稱爲數據模型。它是一種樹形結構(相似硬盤的文件夾和文件的關係)。  web

複製代碼
(root)
  |
  +- user = "Big Joe"
  |
  +- latestProduct
      |
      +- url = "products/greenmouse.html"
      |
      +- name = "green mouse"
複製代碼

  

  早期版本中,能夠從數據模型中選取這些值,使用user和latestProduct.name表達式便可。類比於硬盤的樹形結構,數據模型就像一個文件系統,「(root)」和latestProduct就對應着目錄(文件夾),而user、url和name就是這些目錄中的文件。
整體上,模板和數據模型是FreeMarker來生成輸出所必須的組成部分:模板 + 數據模型 = 輸出

3.基本語法

  • ${...}:FreeMarker將會輸出真實的值來替換大括號內的表達式,這樣的表達式被稱爲interpolation(插值)。
  • 註釋:註釋和HTML的註釋也很類似,可是它們使用<#-- and -->來標識。不像HTML註釋那樣,FTL註釋不會出如今輸出中(不出如今訪問者的頁面中),由於FreeMarker會跳過它們。
  • FTL標籤(FreeMarker模板的語言標籤):FTL標籤和HTML標籤有一些類似之處,可是它們是FreeMarker的指令,是不會在輸出中打印的。這些標籤的名字以#開頭。(用戶自定義的FTL標籤則須要使用@來代替#

  指令數據庫

複製代碼
<#if condition>
    ...
<#elseif condition2>
    ...
<#elseif condition3>
    ...
<#else>
    ...
</#if>
複製代碼

  if、elseif和else指令能夠用來條件判斷是否越過模板的一個部分。condition必須計算成布爾值,不然錯誤將會停止模板處理。elseif和else必須出如今if內部(也就是在if的開始標籤和結束標籤之間)。if中能夠包含任意數量的elseif(包括0個),而結束時else也是可選的。編程

複製代碼
假設 users 包含['Joe', 'Kate', 'Fred'] 序列:
<#list users as user>
    <p>${user}
</#list>
 
輸出:
    <p>Joe
    <p>Kate
    <p>Fred  
複製代碼

  list指令執行在list開始標籤和list結束標籤(list中間的部分)之間的代碼,對於在序列(或集合)中每一個值指定爲它的第一個參數。對於每次
迭代,循環變量將會存儲當前項的值。循環變量僅僅存在於list標籤體內。並且從循環中調用的宏/函數不會看到它(就像它只是局部變量同樣)。
<#list>與<#else>、<#sep>組合是可選的,並且僅從FreeMarker 2.3.23版本開始支持 。後端

複製代碼
將版權信息單獨存放在頁面文件 copyright_footer.html 中:
<hr>
<i>
    Copyright (c) 2000 <a href="http://www.baidu.com">Baidu Inc</a>,
    <br>
    All Rights Reserved.
</i>
 
當須要用到這個文件時,可使用 include 指令來插入:
<html>
    <head>
        <title>Test page</title>
    </head>
    <body>
        <h1>Test page</h1>
        <p>Blah blah...
        <#include "/copyright_footer.html">
    </body>
</html>  
複製代碼

  include能夠在模板中插入另一個FreeMarker模板文件(由路徑參數指定)。被包含模板的輸出格式是在include標籤出現的位置插入的。被包含
的文件和包含它的模板共享變量,就像是被複制粘貼進去的同樣。include指令不能由被包含文件的內容所替代,它只是當FreeMarker每次在模板處
理期間到達include指令時處理被包含的文件。因此對於若是include在list循環之中的例子,能夠爲每一個循環週期內指定不一樣的文件名 。瀏覽器

  空變量    

  數據模型中常常會有可選的變量(有時並不存在)。除了一些人爲緣由致使失誤外,FreeMarker不能引用不存在的變量,除非明確地告訴它當變量不存在時如何處理,以下兩種典型的處理方法:
這部分對程序員而言:一個不存在的變量和一個是null的變量,對於FreeMarker來講是同樣的,因此這裏所指的「丟失」包含這兩種狀況。
不論在哪裏引用變量,均可以指定一個默認值來避免變量丟失這種狀況,經過在變量名後面跟着一個 !和默認值。像下面的這個例子,當user不存在於數據模型時,模板將會將user的值表示爲字符串 「visitor」。(當 user 存在時,模板就會表現出 ${user} 的值):
1
< h1 >Welcome ${user!"visitor"}!</ h1 >
也能夠在變量名後面經過放置??來詢問一個變量是否存在。將它和if指令合併,那麼若是user變量不存在的話將會忽略整個問候的代碼段:
1
2
3
< #if user??>
     <h1>Welcome ${user}!< /h1 >
</ #if>
  關於多級訪問的變量,好比 animals.python.price,書寫代碼:animals.python.price!0當且僅當animals.python永遠存在,而僅僅最後一個子變量price可能不存在時是正確的(這種狀況下假設價格是0)。若是 animals或python不存在,那麼模板處理過程將會以「未定義的變量」錯誤而中止。爲了防止這種狀況的發生, 能夠以下這樣來編寫代碼 (animals.python.price)!0。這種狀況就是說animals或python不存在時,表達式的結果是 0。對於??也是一樣用來的處理這種邏輯的;將animals.python.price??對比(animals.python.price)??來看。

4.性能特色

  基於MVC模式實現,顯示邏輯與業務邏輯分離,便於理解,提升我的專一性。緩存

  4.1. 通用性
  可以生成各類文本:HTMLXMLRTF、Java源代碼等等。
  易於嵌入到產品中:輕量級;不須要Servlet環境。
  插件式模板載入器:能夠從任何源載入模板,如本地文件、數據庫等等。
  能夠按所需生成文本:保存到本地文件;做爲Email發送;從Web應用程序發送它返回給Web瀏覽器。

  4.2. 模板語言
  全部經常使用的指令:include、if/elseif/else、循環結構
  在模板中建立和改變變量。
  幾乎在任何地方均可以使用複雜表達式來指定值。
  命名的宏,能夠具備位置參數和嵌套內容。
  名字空間有助於創建和維護可重用的宏庫,或者將一個大工程分紅模塊,而沒必要擔憂名字衝突。
  輸出轉換塊:在嵌套模板片斷生成輸出時,轉換HTML轉義、壓縮、語法高亮等等;能夠定義本身的轉換。

4.3. 通用數據模型
  FreeMarker不是直接反射到Java對象,Java對象經過插件式對象封裝,以變量方式在模板中顯示。
  可使用抽象(接口)方式表示對象( JavaBeanXML文檔、 SQL查詢結果集等等),告訴模板開發者使用。方法,使其不受技術細節的打擾。
  xml配置
4.4. 爲Web準備
  在模板語言中內建處理典型Web相關任務(如 HTML轉義)的結構。
  可以集成到Model2 Web應用框架中做爲JSP的替代。
  支持JSP標記庫。
  爲MVC模式設計:分離可視化設計和應用程序邏輯;分離頁面設計員和程序員。
4.5. 智能的國際化和本地化
  字符集智能化(內部使用 UNICODE)。
  數字格式本地化敏感。
  日期和時間格式本地化敏感。
  非US 字符集能夠用做標識(如變量名)。
  多種不一樣語言的相同模板。
4.6. XML處理能力
  <#recurse> 和<#visit>指令(2.3版本)用於遞歸遍歷 XML樹。
  在模板中清楚和直接的訪問XML 對象模型 。

5.Freemarker與JSP、velocity的比較

5.1. JSP優勢:
一、功能強大,能夠寫java代碼
二、支持jsp標籤(jsp tag)
三、支持表達式語言(el)
四、官方標準,用戶羣廣,豐富的第三方jsp標籤庫
五、性能良好。jsp編譯成class文件執行,有很好的性能表現
缺點:
複雜頁面使用效率低;使用不當容易破壞mvc結構。

5.2. velocity優勢:
一、不能編寫java代碼,能夠實現嚴格的mvc分離
二、性能良好,聽說比jsp性能還要好些
三、使用表達式語言,聽說jsp的表達式語言就是學velocity的
缺點:
一、不是官方標準
二、用戶羣體和第三方標籤庫沒有jsp多。
三、對jsp標籤支持不夠好。

6.總結

  Freemarker

  優勢:

  6.1. 先後端分離

  6.2. freemarker模板能夠在servlet以外使用,不須要使用類加載器加載,可使用它們來生成電子郵件、 配置文件、 XML 映射等。

  6.3. 高併發下能夠設置頁面靜態化緩存提升查詢性能

  缺點:

  6.4. 不是官方標準,支持的JSP標籤庫少。

  6.5. FreeMarker中的變量必需要賦值,模板發生變化時容易看到過時數據。  

相關文章
相關標籤/搜索