freemaker是一個通用的模版引擎,快速創(chuàng)建想要的字符串。
主要過程
- 配置
- 創(chuàng)建數(shù)據(jù)
- 模版配置
- 數(shù)據(jù)與模版結(jié)合生產(chǎn)字符串
主要參考文檔:http://freemarker.foofun.cn/ref_specvar.html
指令有許多擴(kuò)展功能,請參考上述文檔
1. 配置
不需要重復(fù)創(chuàng)建 Configuration 實(shí)例; 它的代價很高,(window ),尤其是會丟失緩存。Configuration 實(shí)例就是應(yīng)用級別的單例。
// 新建
Configuration cfg = new Configuration(Configuration.VERSION_2_3_22);
// 指定加載目錄,有多種方式
// 直接指定文件絕對路徑
cfg.setDirectoryForTemplateLoading(new File("/where/you/store/templates"));
// 通過class查找文件的base路徑
cfg.setClassForTemplateLoading(class, "/where/you/store/templates")
// 通過class查找文件的base路徑
cfg.setClassForTemplateLoading(class, "/where/you/store/templates")
setClassLoaderForTemplateLoading(class.getClassload(), "/where/you/store/templates")
// 文件格式
cfg.setDefaultEncoding("UTF-8");
// 遇到異常處理選項(xiàng),默認(rèn)即可
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
2. 創(chuàng)建數(shù)據(jù)
只支持一個變量傳入,因此數(shù)據(jù)組裝需要一個大對象傳入
Map<String, Object> map = new HashMap<>();
map.put("tableName", ftlCommonTableDTO.getTableName());
map.put("tableTitles", ftlCommonTableDTO.getTableTitles());
map.put("tableContents", ftlCommonTableDTO.getTableContents());
3. 模版配置
3.1、if
變量是否存在判斷
<#if myOptionalVar??>
when-present
<#else>
when-missing
</#if>
其他邏輯運(yùn)算符都支持不展示
3.2、list
指令list 并且展開變量
<p>We have these animals:
<table border=1>
<#list animals as animal>
<tr><td>${animal.name}<td>
</#list>
</table>
多層嵌套
<p>We have these animals:
<ul border=1>
<#list animals as animal>
<li>
<#list type as animal.type>
<li>${animal.name}</li>
</#list>
</li>
</#list>
</ul>
3.3、內(nèi)建函數(shù)
內(nèi)建函數(shù)更像修飾符,修飾符修飾時能有不同的功能;
比如:
<li>${animal.name?upper_case}</li> 輸出時大寫
其他指令參考http://freemarker.foofun.cn/dgui_quickstart_template.html#autoid_3
4. 數(shù)據(jù)與模版結(jié)合生產(chǎn)字符串
數(shù)據(jù)模型 (root) 和一個模板 (temp), 由模板的 process 方法完成的。
Template template = configuration.getTemplate("test", "UTF-8");
Writer out = new OutputStreamWriter(System.out);
temp.process(root, out);
// 這里System.out直接輸出打印, 實(shí)際中需要用變量接收;這都需要使用到outputStream,可以用字節(jié)數(shù)組接收ByteArrayOutputStream
這會向你的終端輸出你在模板開發(fā)指南部分的 第一個示例 中看到的內(nèi)容。
Java I/O 相關(guān)注意事項(xiàng):基于 out 對象,必須保證 out.close() 最后被調(diào)用。當(dāng) out 對象被打開并將模板的輸出寫入文件時,這是很電影的做法。其它時候, 比如典型的Web應(yīng)用程序,那就 不能 關(guān)閉 out 對象。FreeMarker 會在模板執(zhí)行成功后 (也可以在 Configuration 中禁用) 調(diào)用 out.flush(),所以不必為此擔(dān)心。
請注意,一旦獲得了 Template 實(shí)例, 就能將它和不同的數(shù)據(jù)模型進(jìn)行不限次數(shù) (Template實(shí)例是無狀態(tài)的)的合并。此外, 當(dāng) Template 實(shí)例創(chuàng)建之后 test.ftl 文件才能訪問,而不是在調(diào)用處理方法時。
demo
public static String getContent(String ftlName, Map<String, ? extends Object> map) {
ByteArrayOutputStream baos = null;
OutputStreamWriter osw = null;
String content = "";
try {
Template template = configuration.getTemplate(ftlName, "UTF-8");
baos = new ByteArrayOutputStream();
osw = new OutputStreamWriter(baos);
template.process(map, osw);
byte[] bytes = baos.toByteArray();
content = new String(bytes);
} catch (Exception e) {
System.out.println(e.getMessage());
} finally {
if (osw != null) {
try {
osw.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
if (baos != null) {
try {
baos.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
return content;
}