FreeMarker入門

技術小能手發表於2018-07-30

FreeMarker入門

什麼是 FreeMarker?

FreeMarker 是一款模板引擎:即基於模板和資料來源生成輸出文字(html網頁,配置檔案,電子郵件,原始碼)的通用工具。它是一個 java 類庫,最初被設計用來在MVC模式的Web開發框架中生成HTML頁面,它沒有被繫結到Servlet或HTML或任意Web相關的東西上。也可以用於非Web應用環境中。

模板編寫使用FreeMarker Template Language(FTL)。使用方式類似JSP的EL表示式。模板中專注於如何展示資料,模板之外可以專注於要展示什麼資料。

FreeMarker入門

為什麼用 FreeMarker?

  1. FreeMarker 基於資料模型和模板來渲染,將業務邏輯和表現層分離。 JSP開發中,頁面會有大量業務邏輯,不利於維護和閱讀,使用FreeMarker可以避免這一問題。

  2. **有利於分工合作。**HTML設計師可以關注頁面的設計無需面對頁面的業務邏輯,同時修改頁面程式碼也不需要程式設計師編重新譯程式碼。

  3. **提高開發效率。**相對於JSP,FreeMarker不需要每次修改後重新編譯,因此在開發除錯中可以有效節省時間。

  4. **有利於提高訪問速度。**對於不會頻繁發生變化的頁面,建議使用FreeMarker生成的靜態頁面。而不是每次都要動態生成的JSP頁面。

  5. **可以提高併發量。**例如單臺tomcat容器只支援幾百併發,如果將靜態頁面放到效能更好的nginx伺服器上,可以支援幾萬的併發。

  6. 靜態頁面對SEO更友好。

  7. **不佔用JVM的PermGen space。**因為不會被編譯成類,所以不會佔用web伺服器永生代的空間,避免OutOfMemoryError:PermGen space的問題。

怎麼用 FreeMarker?

在java中使用

	@Test
	public void testFreeMarker() throws Exception {
		// 把freemarker的jar包新增到工程中
		//建立一個Configuration物件
		Configuration configuration = new Configuration(Configuration.getVersion());
		// 告訴config物件模板檔案存放的路徑。
		configuration.setDirectoryForTemplateLoading(new File("ftl directory absolute path"));
		// 設定config的預設字符集。一般是utf-8
		configuration.setDefaultEncoding("utf-8");
		//從config物件中獲得模板物件。需要制定一個模板檔案的名字。
		Template template = configuration.getTemplate("test.ftl");
		//建立模板需要的資料集。可以是一個map物件也可以是一個pojo,把模板需要的資料都放入資料集。
		Map root = new HashMap<>();
		root.put("hello", "hello freemarker");
		//建立一個Writer物件,指定生成的檔案儲存的路徑及檔名。
		Writer out = new FileWriter(new File("out html file absolute path"));
		//呼叫模板物件的process方法生成靜態檔案。需要兩個引數資料集和writer物件。
		template.process(root, out);
		//關閉writer物件。
		out.flush();
		out.close();
	}
複製程式碼

模板載入器

當然也可以不指定絕對路徑,使用模板載入器,FreeMarker提供了模板載入器可以直接從資料來源載入模板。

  • ClassTemplateLoader:從classpath中載入模板。

  • FileTemplateLoader:在檔案系統中從指定資料夾載入模板。

  • StringTemplateLoader:從一個字串 Map 中載入模板。

  • URLTemplateLoader:從 URL 中載入模板。 你必須要實現 getURL 方法。

  • WebappTemplateLoader:從 servlet 上下文中載入模板。

使用方式:

Configuration configuration = new Configuration();
configuration.setTemplateLoader(
new WebappTemplateLoader(servletContext, "WEB-INF/content"));
複製程式碼

在專案中使用

在專案中使用的話,可以直接託管給框架即可。

新增依賴

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-context-support</artifactId>
	<version>4.1.3.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.freemarker</groupId>
	<artifactId>freemarker</artifactId>
	<version>2.3.23</version>
</dependency>
複製程式碼

配置spring

<bean id="freemarkerConfig"
		class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
		<property name="templateLoaderPath" value="/WEB-INF/ftl/" />
		<property name="defaultEncoding" value="UTF-8" />
	</bean>
複製程式碼

然後使用時從FreeMarkerConfigurer拿到Configuration物件:

Configuration configuration = freeMarkerConfigurer.getConfiguration();
複製程式碼

FreeMarker 基本語法

簡單型別

使用類似EL表示式。

${hello}
複製程式碼

包裝型別

<html>
<head>
	<title>${title}</title>
</head>
<body>
	<label>學號:</label>${student.id}<br>
	<label>姓名:</label>${student.name}<br>
</body>
</html>
複製程式碼

遍歷集合/陣列

<#list people as p>
	${p.id}/${p.name}
</#list>
複製程式碼

獲取當前迭代索引

<#list people as p
	${p_index}
</#list>
複製程式碼

新增判斷條件

<#if 條件>
<#else>
</#if>
複製程式碼

日期型別

#預設格式
1:date
${cur_time?date}
2:datetime
${cur_time?datetime}
3:time
${cur_time?time}

#自定義格式
${cur_time?string("yyyy-MM-dd HH:mm:ss")}
複製程式碼

處理 null 值

map.put("val",null)

val值為:${val!}
複製程式碼

當val為空時,顯示為空字串,即

val值為:
複製程式碼

也可以指定值為空時的預設值。

${val!"預設值"}
複製程式碼

也可以使用條件語句做非空判斷。

<#if curdate ??>
	當前日期:${curdate?string("yyyy/MM/dd HH:mm:ss")}
	<#else>
	curdate屬性為null
	</#if>
複製程式碼

include

可以引入其他模板片段。

<#include "/include/head.ftl">
複製程式碼

json 支援

?eval可以將字串轉為json物件,然後在模板中當包裝型別使用。

<#assign user = userString?eval>
User:${user.name}
複製程式碼

共享變數

可以設定自動新增到所有模板的資料,這樣就可以在所有模板中使用。

configuration.setSharedVariable("share_value_key", "share_value");
複製程式碼

補充

  • 需要使用FreeMarker的頁面在資料庫更新時要及時更新,否則使用者訪問到的會是過期的頁面。

  • FreeMarker資料模型的map的key只可以是String型別。

相關文章