Freemarker模版详细介绍
FreeMarker
1.主要內容
2. FreeMarker概述
2.1.FreeMarker概念
FreeMarker 是一款 模板引擎: 即一種基于模板和要改變的數據,并用來生成輸出文本(HTML網頁,電子郵件,配置文件,源代碼等)的通用工具。 是一個Java類庫。
FreeMarker 被設計用來生成 HTML Web 頁面,特別是基于 MVC模式的應用程序,將視圖從業務邏輯中抽離處理,業務中不再包括視圖的展示,而是將視圖交給 FreeMarker 來輸出。雖然FreeMarker 具有一些編程的能力,但通常由 Java 程序準備要顯示的數據,由 FreeMarker 生成頁面,通過模板顯示準備的數據(如下圖):
FreeMarker不是一個Web應用框架,而適合作為Web應用框架一個組件。
FreeMarker與容器無關,因為它并不知道HTTP或Servlet。
FreeMarker同樣可以應用于非Web應用程序環境。
FreeMarker更適合作為Model2框架(如Struts)的視圖組件,你也可以在模板中使用JSP標記庫。
2.2FreeMarker的特性
2.2.1. 通用目標
能夠生成各種文本:HTML、XML、RTF、Java 源代碼等等易于嵌入到你的產品中:輕量級;不需要 Servlet 環境插件式模板載入器:可以從任何源載入模板,如本地文件、數據庫等等;
2.2.2 強大的模板語言
所有常用的指令:include、if/elseif/else、循環結構在模板中創建和改變變量幾乎在任何地方都可以使用復雜表達式來指定值命名的宏,可以具有位置參數和嵌套內容名字空間有助于建立和維護可重用的宏庫,或將大工程分成模塊,而不必擔心名字沖突。
2.2.3. 通用數據模型
FreeMarker不是直接反射到Java對象,Java對象通過插件式對象封裝,以變量方式在模板中顯示你可以使用抽象(接口)方式表示對象(JavaBean、XML文檔、SQL查詢結果集等等),告訴模板開發者使用方法,使其不受技術細節的打擾
2.2.4. 為Web準備
在模板語言中內建處理典型Web相關任務(如HTML轉義)的結構能夠集成到Model2 Web應用框架中作為JSP的替代
支持JSP標記庫為MVC模式設計:分離可視化設計和應用程序邏輯;分離頁面設計員和程序員
2.2.5. 智能的國際化和本地化
字符集智能化(內部使用UNICODE)
數字格式本地化敏感
日期和時間格式本地化敏感
非US字符集可以用作標識(如變量名)
多種不同語言的相同模板
2.2.6. 強大的XML處理能力
<#recurse> 和 <#visit> 指令(2.3版本)用于遞歸遍歷XML樹。在模板中清楚和直接的訪問XML對象模型。開源論壇 JForum 就是使用了 FreeMarker 做為頁面模板。
2.3. FreeMarker環境搭建
2.3.1. 新建 Maven Web項目
2.3.2. 配置坐標依賴和部署插件
pom.xml
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.xxxx</groupId><artifactId>freemarker</artifactId><version>1.0-SNAPSHOT</version><packaging>war</packaging><name>freemarker Maven Webapp</name><!-- FIXME change it to the project's website --><url>http://www.example.com</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target></properties><dependencies><!-- freemarker的坐標依賴 --><dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.23</version></dependency><!-- servlet-api的坐標依賴 --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.0.1</version></dependency></dependencies><build><finalName>freemarker</finalName><plugins><!-- 配置jetty插件 --><plugin><groupId>org.eclipse.jetty</groupId><artifactId>jetty-maven-plugin</artifactId><version>9.2.1.v20140609</version></plugin></plugins></build> </project>2.3.3. 修改配置文件 web.xml
在項目的webapp/WEB-INF目錄下的web.xml文件中,添加freemarker 相關 servlet 配置
<!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app><display-name>Archetype Created Web Application</display-name><!-- FreeMarker 的Servlet配置 --><servlet><servlet-name>freemarker</servlet-name><servlet-class>freemarker.ext.servlet.FreemarkerServlet</servlet-class><init-param><!-- 模板路徑 --><param-name>TemplatePath</param-name><!-- 默認在webapp目錄下查找對應的模板文件 --><param-value>/</param-value></init-param><init-param><!-- 模板默認的編碼:UTF-8 --><param-name>default_encoding</param-name><param-value>UTF-8</param-value></init-param></servlet><!-- 處理所有以.ftl結尾的文件;ftl是freemarker默認的文件后綴 --><servlet-mapping><servlet-name>freemarker</servlet-name><url-pattern>*.ftl</url-pattern></servlet-mapping></web-app>2.3.4. 編寫Servlet類
package com.xxxx.controller;import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet("/f01") public class Servlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//添加數據req.setAttribute("msg","Hello Freemarker!!");//請求轉發到ftl文件中req.getRequestDispatcher("template/f01.ftl").forward(req,resp);} }2.3.5. 新建模板文件 ftl
2.3.6. 啟動項目
2.3.7. 訪問項目
瀏覽器地址欄輸入:http://localhost:8989/f01
3. FreeMarker 數據類型
Freemarker 模板中的數據類型由如下幾種:
- 布爾型:等價于 Java 的 Boolean 類型,不同的是不能直接輸 出,可轉換為字符串輸出
- 日期型:等價于 java 的 Date類型,不同的是不能直接輸出, 需要轉換成字符串再輸出
- 數值型:等價于 java 中的 int,float,double 等數值類型有三種顯示形式:數值型(默認)、貨幣型、百分比型
- 字符型:等價于 java 中的字符串,有很多內置函數
- sequence 類型:等價于java 中的數組,list,set 等集合類型
- hash 類型:等價于 java 中的 Map 類型
3.1. 布爾類型
3.2. 日期類型
3.3. 數值類型
3.4. 字符串類型
3.4.1字符串空值情況處理
FreeMarker 的變量必須賦值,否則就會拋出異常。而對于FreeMarker 來說,null值和不存在的變量是完全一樣的,因為FreeMarker 無法理解 null 值。
FreeMarker 提供兩個運算符來避免空值:
① !:指定缺失變量的默認值 ${value!}:如果value值為空,則默認值是空字符串
${value!“默認值”}:如果value值為空,則默認值是字符串"默認值"
② ?? :判斷變量是否存在 如果變量存在,返回true,否則返回 false
${(value??)?string}
3.5. sequence類型
3.6. hash 類型
4.FreeMarker 常見指令
4.1. assign 自定義變量指令
使用 assign 指令你可以創建一個新的變量, 或者替換一個已經存在的變量。
<#--assign 自定義變量指令語法:<#assign 變量名=值><#assign 變量名=值 變量名=值> (定義多個變量) --> <#assign str="hello"> ${str} <br> <#assign num=1 names= ["zhangsan","lisi","wangwu"] > ${num} -- ${names?join(",")}4.2. if elseif else 邏輯判斷指令
可以使用 if , elseif 和 else 指令來條件判斷是否滿足某些條件。
<-- if, else, elseif 邏輯判斷指令格式:<#if condition>...<#elseif condition2>...<#elseif condition3>...<#else>...</#if>注:1. condition, condition2等:將被計算成布爾值的表達式。2. elseif 和 else 指令 是可選的。--> <h5> 2. if, else, elseif 邏輯判斷指令</h5> <#assign score = 60> <#if score lt 60 ><h6>你個小渣渣!</h6><#elseif score == 80><h6>分不在高,及格就行!</h6><#elseif score gt 60 && score lt 80 ><h6>革命尚未成功,同志仍需努力!</h6><#else ><h6>哎喲不錯哦!</h6> </#if> <#assign list=""> <#if list??>數據存在<#else >數據不存在 </#if> <br> <#if list2??>數據存在 <#else >數據不存在 </#if> <br><hr>4.3. list 遍歷指令
可以使用 list 指令來對序列進行遍歷。
<-- 3. list指令格式1:<#list sequence as item></#list>格式2:<#list sequence as item><#else>當沒有選項時,執行else指令</#list>注:1. else 部分是可選的2. sequence: 想要迭代的項,可以是序列或集合的表達式3. item: 循環變量 的名稱4. 當沒有迭代項時,才使用 else 指令, 可以輸出一些特殊的內容而不只是空在那里 --> <h5>3. list指令</h5> <#assign users = ["張三","李四","王五"]> <#list users as user>${user} | </#list> <br> <#--判斷數據不為空,再執行遍歷 (如果序列不存在,直接遍歷會報錯)--> <#if users2??><#list users2 as user>${user}</#list> </#if> <br> <#-- 當序列沒有數據項時,使用默認信息 --> <#assign users3 = []> <#list users3 as user>${user} |<#else >用戶數據不存在! </#list> <hr>4.4. macro 自定義指令
可以使用 macro 指令來自定義一些自定義指令。
<--4. macro 自定義指令 (宏)1. 基本使用格式:<#macro 指令名>指令內容</#macro>使用:<@指令名></@指令名>2. 有參數的自定義指令格式:<#macro 指令名 參數名1 參數名2>指令內容</#macro>使用:<@指令名 參數名1=參數值1 參數名2=參數值2></@指令名>注:1. 指令可以被多次使用。2. 自定義指令中可以包含字符串,也可包含內置指令--> <h5>4. macro 自定義指令</h5> <#-- 自定義指定 --> <#macro address>? 1999–2015 The FreeMarker Project. All rights reserved. </#macro> <#-- 使用自定義指令 --> <@address></@address> <#macro address02><h3> ? 1999–2015 The FreeMarker Project. All rights reserved.</h3> </#macro> <@address02></@address02> <@address02></@address02> <@address02></@address02> <#-- 自定義有參數的指令 --> <#macro queryUserByName uname>通過用戶名查詢用戶對象 - ${uname} </#macro> <@queryUserByName uname="admin"></@queryUserByName> <br> <#macro queryUserByName02 uname upwd phone>多條件查詢用戶對象 - ${uname} - ${upwd} - ${phone} </#macro> <@queryUserByName02 uname="zhangsan" upwd="123456" phone="1587656789"></@queryUserByName02> <hr> <#-- 自定義指令中包含內置指令 --> <#macro cfb><#list 1..9 as i><#list 1..i as j>${j} * ${i} = ${j*i} </#list><br></#list> </#macro> <@cfb></@cfb> <@cfb></@cfb> <hr> <#macro cfb02 num><#list 1..num as i><#list 1..i as j>${j} * ${i} = ${j*i} </#list><br></#list> </#macro> <@cfb02 num=5></@cfb02> <@cfb02 num=7></@cfb02> <hr>4.5. nested 占位指令
nested 指令執行自定義指令開始和結束標簽中間的模板片段。嵌套的片段可以包含模板中任意合法的內容。
<#--nested 占位指令nested 相當于占位符,一般結合macro指令一起使用。可以將自定義指令中的內容通過nested指令占位,當使用自定義指令時,會將占位內容顯示。 --> <#macro test>這是一段文本!<#nested><#nested> </#macro> <@test><h4>這是文本后面的內容!</h4></@test>4.6. import 導入指令
import 指令可以引入一個庫。也就是說,它創建一個新的命名空間, 然后在那個命名空間中執行給定路徑的模板。可以使用引入的空間中的指令。
commons.ftl
<#macro cfb> <#list 1..9 as i> <#list 1..i as j> ${j}*${i}=${j*i} </#list> <br> </#list> </#macro>在其他ftl頁面中通過import導入commons.ftl的命名空間,使用該命名空間中的指令
test.ftl
<#-- 導入命名空間 --> <#import "commons.ftl" as common> <#-- 使用命名空間中的指令 --> <@common.cfb></@common.cfb>4.7. include 包含指令
可以使用 include 指令在你的模板中插入另外一個 FreeMarker模板文件 。 被包含模板的輸出格式是在 include 標簽出現的位置插入的。 被包含的文件和包含它的模板共享變量,就像是被復制粘貼進去的一樣。
<#--包含指令(引入其他頁面文件) include--> <#--html文件--> <#include "test.html"> <#--freemarker文件--> <#include "test.ftl"> <#--text文件--> <#include "test.txt">5. FreeMarker 頁面靜態化
通過上述介紹可知 Freemarker 是一種基于模板的、用來生成輸出文本的通用工具,所以 我們必須要定制符合自己業務的模板,然后生成自己的 html 頁面。Freemarker 是通過freemarker.template.Configuration 這個對象對模板進行加載的(它也處理創建和緩存預 解析模板的工作),然后我們通過getTemplate 方法獲得你想要的模板,有一點要記住freemarker.template.Configuration 在你整個應用必須保證唯一實例。
5.1. 定義模板
news.ftl
<#-- 新聞標題 --> <h1>${title}</h1> <p> 新聞來源:${source} 發布時間:${pubTime? sring("yyyy-MM-dd HH:mm")} </p> <#-- 新聞內容 --> <p> ${content} </p>5.2. 加載模板
package com.xxxx.servlet;import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException;import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.HashMap; import java.util.Map;@WebServlet("/news") public class NewsServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 實例化模板對象Configuration configuration = new Configuration();// 設置加載模板的上下文 以及加載模板的路徑 (模板存放路徑)configuration.setServletContextForTemplateLoading(getServletContext(),"/template");// 設置模板的編碼格式configuration.setDefaultEncoding("UTF-8");// 加載模板文件 獲取模板對象Template template = configuration.getTemplate("news.ftl");// 設置數據模型Map<String,Object> map = new HashMap<>();map.put("title","【戰“疫”說理】良好的公民素養和國民心態是“硬核”力量");map.put("source","經濟日報-中國經濟網");map.put("pubTime","2020年03月16日 10:00");map.put("content","公共性的社會大事件,是檢驗和透視公民素養和國民心態的一個重要窗口。" +"在突襲而至的新冠肺炎疫情面前,一方面,抗擊疫情的過程就是淬煉公民素養和國民心態的熔爐;另一方面,良好的公民素養和國民心態也是疫情防控的“硬核”力量,更是推動戰“疫”積極向好態勢不斷拓展的精神之盾。\n" +"\n疫情防控,既是大戰,也是大考。涵養良好的公民素養和國民心態,是疫情期間擺在我們面前的考題,同時也是提升國家治理能力過程中需要面對的課題。\n" +"\n著眼三個方面 提升科學素養\n\n疫情面前,每個人都是防控鏈條中的重要一環。做好自我保護,既是對自己、家人負責,也是對社會負責。有效做好科學防控,每個人都應具備必要的科學素養。");// 獲取項目的根目錄String basePath = req.getServletContext().getRealPath("/");// 設置html的存放路徑File htmlFile = new File(basePath + "/html");// 判斷文件(目錄)是否存在if (!htmlFile.exists()) {// 如果文件目錄不存在,則新建文件目錄htmlFile.mkdir();}// 得到生成的文件名 (生成隨機不重復的文件名)String fileName = System.currentTimeMillis() + ".html";// 創建html文件File file = new File(htmlFile,fileName);// 獲取文件輸出流FileWriter writer = new FileWriter(file);// 生成html (將數據模型填充到模板中)try {template.process(map,writer);} catch (TemplateException e) {e.printStackTrace();} finally {// 關閉資源writer.flush();writer.close();}} }5.3. 生成對應的html文件
瀏覽器地址欄輸入:http://localhost:8989/news
生成的文件存放在當前項目的webapp目錄下的html目錄中。
6. FreeMarker 運算符
6.1. 算術運算符
<!-- 算術運算 +、-、*、/、% --> <#assign a1 = 8 a2 = 2 > ${a1} + ${a2} = ${a1 + a2} <br/> ${a1} - ${a2} = ${a1 - a2} <br/> ${a1} * ${a2} = ${a1 * a2} <br/> ${a1} / ${a2} = ${a1 / a2} <br/> ${a1} % ${a2} = ${a1 % a2} <br/> <!--字符串運算--> ${"hello" + "," + "freemarker"}6.2. 邏輯運算符
<#-- 邏輯運算符 &&、||、! -->6.3. 比較運算符
<#-- 比較運算符 > (gt): 大于號,推薦使用 gt < (lt): 小于號,推薦使用 lt >= (gte): 大于等于, 推薦是用 gte <= (lte): 小于等于,推薦使用 lte == : 等于 != : 不等于 -->6.4. 空值運算符
<#-- 空值運算符 1. ??:判斷是否為空,返回布爾類型 如果不為空返回 false, 如果為空返回 true,不能 直接輸出 ${(name??)?string} 2. !: 設置默認值,如果為空,則設置默認值 1. 設置默認為空字符串: ${name!} 2. 設置指定默認值 ${name!'zhangsan'} -->總結
以上是生活随笔為你收集整理的Freemarker模版详细介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OGG mgr定期清理tail 文件
- 下一篇: 弘辽科技:京东店铺布局,打破无流量无转化