FreeMarker入門

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

什麼是FreeMarker?

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

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

image

為什麼用FreeMarker?

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

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

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

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

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

靜態頁面對SEO更友好。

不佔用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型別。

原文釋出時間為:2018-07-28
本文來自雲棲社群合作伙伴“Java雜記”,瞭解相關資訊可以關注“Java雜記


相關文章