Java模板引擎 FreeMarker

概念


FreeMarker是一個模板引擎,一個基於模板生成文本輸出的通用工具,使用純Java編寫。

它是爲Java程序猿提供的一個開發包。它不是面向終於用戶的,而是爲程序猿提供的一款可以嵌入他們所開發產品的應用程序。html



介紹


那麼。FreeMarker是一款如何的工具呢?FreeMarker其實是被設計用來生成HTML Web頁面,尤爲是經過實現了基於MVC模式的Java Servlet應用程序。使用MVC模式的動態頁面的設計構思使得你可以將前端設計師從程序猿中分離出來。所有人各司其職,發揮其最擅長的一面。

網頁設計師可以改寫頁面的顯示效果而不受程序猿編譯代碼的影響,因爲應該程序的邏輯和頁面設計已經被分開了。頁面模板代碼不會收到複雜程序代碼的影響。

這樣的分離的思想即使對一個程序猿和頁面設計師是同一我的的項目來講也都是很實用的,因爲分離使得代碼保持簡潔而且易於維護。前端


雖然FreeMarker也擁有一些編程能力,但一般由Java程序準備要顯示的數據,由FreeMarker生成頁面,經過模板顯示準備的數據(例如如下圖)。


FreeMarker不是一個Web應用框架。而適合做爲Web應用框架的一個組件。但是FreeMarker引擎自己並不知道HTTP協議或Java Servlet的存在。它只來生成文本內容。既然是這樣,它也很適用於非Web應用程序的開發環境。知識要注意的是。咱們使用FreeMarker做爲視圖層的組件,是爲了給諸如Struts這種Model2應用框架提供現成的解決方式,你也可以在模板中使用JSP標記庫。



特性

  • 通用目標
易於嵌入到你的產品中,輕量級,不需要Servlet環境

能夠生成各類文本:HTML、XML、RTF、Java源碼等等

插件式模板加載器。可以從不論什麼源加載模板。如本地文件、數據庫等等

你可以按本身所需生成文本,保存到本地文件。做爲Email發送,從Web應用程序發送它返回給Web瀏覽器

  • 強大的模板語言
在模板中建立和改變變量

命名的宏,可以具備位置參數和嵌套內容

差點兒在不論什麼地方都可以使用複雜表達式來指定值

所有常用的指令,include、if/elseif/else、循環結構

名字空間有助於創建和維護可重用的宏庫,或者將一個大project分紅模塊,而沒必要操心名字衝突

輸出轉換塊,在嵌套模板片斷生成輸出時。轉換HTML轉義、壓縮、語法高亮等等。你可以定義本身的轉換

  • 通用數據模型
FreeMarker不是直接反射到Java對象,Java對象經過插件式對象封裝,以變量方式在模板中顯示

你可以使用抽象(接口)方式表示對象(JavaBean、XML文檔、SQL查詢結果集等),告訴模板開發人員用法。使其不受技術細節的打攪

  • 爲Web準備
支持JSP標記庫

能夠集成到Model2 Web應用框架中做爲JSP的替代

在模板語言中內建處理典型Web相關任務(如HTML轉義)的結構

爲MVC模式設計,分離可視化設計和應用程序邏輯,分離頁面設計師和程序猿

  • 智能的國際化和本地化
數字格式本地化敏感

多種不一樣語言的一樣模板

日期和時間格式本地化敏感

字符集智能化(內部使用UNICODE)

非US字符集可以用做標識(如變量名)

  • 強大的XML處理能力
在模板中清楚和直覺的訪問XML對象模型

<#recurse>和<#visit>指令用於遞歸遍歷XML樹


優點

  • 可以完全的分離表現層和業務邏輯
使用JSP開發過程當中,在頁面中大量的存在業務邏輯代碼,使得頁面的內容很混亂,在後期大量的改動維護過程當中就變得很的困難。


FreeMarker不支持Java腳本代碼。FreeMarker的原理是,模板+數據模型=輸出。

模板僅僅負責數據在頁面中的表現。不涉及不論什麼的邏輯代碼,而所有的邏輯都是由數據模型來處理的。用戶終於看到的輸出是模板和數據模型合併後建立的。java


  • 可以提升開發效率
在以往的開發中。使用的都是JSP頁面來展現數據的。即所謂的表現層。

咱們都知道。JSP在第一次運行的時候需要轉換成Servlet類,開發階段進行功能調試時,需要頻繁的改動JSP,每次改動都要編譯和轉換。那麼試想一下,一天中咱們浪費在程序編譯的時間有多少。數據庫


相對於JSP來講。FreeMarker模板技術不存在編譯和轉換的問題,因此就不會存在上述問題。而且開發過程當中,咱們再沒必要等待界面設計開發者完畢頁面原型後,咱們再來開發程序。


而且,一些特定的系統。比方OA工做流系統中,就需要動態生成表單技術,這就爲其提供了很是好的實現根據。

使得在整個流程的進行中。生成不一樣的表單就簡單了很是多。編程

  • 使得開發過程當中的人員分工更加明白
以往用JSP顯示數據時,一些程序猿並不熟悉界面設計技術。反之界面開發者。也並不熟悉程序語言。對二者而言,交替性的工做自己就有難度。有時候稍有不慎。可能會將整個頁面元素刪除或去掉了某個程序符號。使得頁面走樣或程序錯誤,這樣就需要兩方相互溝通協做,解決出現的問題。有時候因爲項目中的時間、任務量等因素的存在,可能這個工做就由一我的來完畢,這樣就可能加大某一方開發者的工做量。

使用FreeMarker後,做爲界面開發者。僅僅專心建立HTML文件、圖像以及Web頁面的其它可視化方面,不用理會數據;而程序開發者則專一於系統實現。負責爲頁面準備要顯示的數據。



不足

  • 在改動模板後,可能會看到已通過期的數據
使用FreeMarker模板技術,生成靜態的HTML頁面後。假設一旦模板改變。而沒有及時更新模板生成的HTML頁面的話。用戶看到的就是過時的數據。 
  • FreeMarker的變量必須有值
FreeMarker模板技術在應用過程當中,FreeMarker中的變量必須要賦值,假設不賦值,那麼就會拋出異常。

FreeMarker沒有一個默認的null處理。甚至也不接受一個null值。想避免錯誤就要應用if/elseif/else 指令進行判段,假設對每一個變量都推斷的話,那麼則反而添加了編程的麻煩。 瀏覽器

  • FreeMarker的Map限定Key必須是String。其它數據類型沒法操做
Map問題,即FreeMarker中不能支持非String的Key值。這樣在進行一些複雜迭代時就需要做一些其它的轉換。如將一個Map拆分爲兩個或多個Map。

  • FreeMarker不支持集羣應用
爲了編成的方便性,把序列化的東西都放到了Session中,如Session,request等。在開發的過程當中確實方便,但假設將應用放到集羣中,就會出現錯誤。

 



一個小Demo


首先。需要下載FreeMarker的jar包,這裏提供一個下載連接: freemarker.jar

而後,將這個freemarker.jar放到Web項目的  WebRoot\WEB-INF\lib 文件夾下

最後,我把本身寫的測試類貼出來,分享一下。

FreemarkerTest類 代碼
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
import junit.framework.TestCase;

public class FreemarkerTest extends TestCase {

	private String dir = "E:/.../OA/TestTotal/src/com/bjsxt/oa/freemarker";

	public void testFreemarker() {
		Configuration cfg = new Configuration();

		try {
			// 從哪裏載入模板文件
			cfg.setDirectoryForTemplateLoading(new File(dir));
			
			// 定義模版的位置,從類路徑中,相對於FreemarkerManager所在的路徑載入模版
			// cfg.setTemplateLoader(new ClassTemplateLoader(FreemarkerManager.class, "templates"))

			// 設置對象包裝器
			cfg.setObjectWrapper(new DefaultObjectWrapper());

			// 設置異常處理器
			cfg
					.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);

			// 定義數據模型
			Map root = new HashMap();
			root.put("abc", "世界。你好");

			// 經過freemarker解釋模板,首先需要得到Template對象
			Template template = cfg.getTemplate("test.ftl");

			// 定義模板解釋完畢以後的輸出
			PrintWriter out = new PrintWriter(new BufferedWriter(
					new FileWriter(dir+"/out.txt")));

			
			try {
				// 解釋模板
				template.process(root, out);
			} catch (TemplateException e) {
				e.printStackTrace();
			}

		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}


如下是定義的模板 test.ftl

test.flt 代碼
第一個測試程序:${abc}


最後執行的結果例如如下

輸出了out.txt文件,out.txt文件裏的內容例如如下:
第一個測試程序:世界。你好

相關文章
相關標籤/搜索