freemarker入门教程
轉(zhuǎn)載自http://demojava.iteye.com/blog/800204?
以下內(nèi)容全部是網(wǎng)上收集:?
FreeMarker的模板文件并不比HTML頁面復(fù)雜多少,FreeMarker模板文件主要由如下4個部分組成:?
1,文本:直接輸出的部分?
2,注釋:<#-- ... -->格式部分,不會輸出?
3,插值:即${...}或#{...}格式的部分,將使用數(shù)據(jù)模型中的部分替代輸出?
4,FTL指令:FreeMarker指定,和HTML標(biāo)記類似,名字前加#予以區(qū)分,不會輸出?
下面是一個FreeMarker模板的例子,包含了以上所說的4個部分?
<html><br>?
<head><br>?
<title>Welcome!</title><br>?
</head><br>?
<body><br>?
<#-- 注釋部分 --><br>?
<#-- 下面使用插值 -->?
<h1>Welcome ${user} !</h1><br>?
<p>We have these animals:<br>?
<u1><br>?
<#-- 使用FTL指令 -->?
<#list animals as being><br>?
?? <li>${being.name} for ${being.price} Euros<br>?
<#list><br>?
<u1><br>?
</body><br>?
</html>?
1, FTL指令規(guī)則?
在FreeMarker中,使用FTL標(biāo)簽來使用指令,FreeMarker有3種FTL標(biāo)簽,這和HTML標(biāo)簽是完全類似的.?
1,開始標(biāo)簽:<#directivename parameter>?
2,結(jié)束標(biāo)簽:</#directivename>?
3,空標(biāo)簽:<#directivename parameter/>?
實際上,使用標(biāo)簽時前面的符號#也可能變成@,如果該指令是一個用戶指令而不是系統(tǒng)內(nèi)建指令時,應(yīng)將#符號改成@符號.?
使用FTL標(biāo)簽時, 應(yīng)該有正確的嵌套,而不是交叉使用,這和XML標(biāo)簽的用法完全一樣.如果全用不存在的指令,FreeMarker不會使用模板輸出,而是產(chǎn)生一個錯誤消息.FreeMarker會忽略FTL標(biāo)簽中的空白字符.值得注意的是< , /> 和指令之間不允許有空白字符.?
2, 插值規(guī)則?
FreeMarker的插值有如下兩種類型:1,通用插值${expr};2,數(shù)字格式化插值:#{expr}或#{expr;format}?
2.1 通用插值?
對于通用插值,又可以分為以下4種情況:?
1,插值結(jié)果為字符串值:直接輸出表達式結(jié)果?
2,插值結(jié)果為數(shù)字值:根據(jù)默認(rèn)格式(由#setting指令設(shè)置)將表達式結(jié)果轉(zhuǎn)換成文本輸出.可以使用內(nèi)建的字符串函數(shù)格式化單個插值,如下面的例子:?
<#settion number_format="currency"/>?
<#assign answer=42/>?
${answer}?
${answer?string} <#-- the same as ${answer} -->?
${answer?string.number}?
${answer?string.currency}?
${answer?string.percent}?
${answer}?
輸出結(jié)果是:?
$42.00?
$42.00?
42?
$42.00?
4,200%?
3,插值結(jié)果為日期值:根據(jù)默認(rèn)格式(由#setting指令設(shè)置)將表達式結(jié)果轉(zhuǎn)換成文本輸出.可以使用內(nèi)建的字符串函數(shù)格式化單個插值,如下面的例子:?
${lastUpdated?string("yyyy-MM-dd HH:mm:ss zzzz")}?
${lastUpdated?string("EEE, MMM d, ''yy")}?
${lastUpdated?string("EEEE, MMMM dd, yyyy, hh:mm:ss a '('zzz')'")}?
輸出結(jié)果是:?
2008-04-08 08:08:08 Pacific Daylight Time?
Tue, Apr 8, '03?
Tuesday, April 08, 2003, 08:08:08 PM (PDT)?
4,插值結(jié)果為布爾值:根據(jù)默認(rèn)格式(由#setting指令設(shè)置)將表達式結(jié)果轉(zhuǎn)換成文本輸出.可以使用內(nèi)建的字符串函數(shù)格式化單個插值,如下面的例子:?
<#assign foo=true/>?
${foo?string("yes", "no")}?
輸出結(jié)果是:?
yes?
2.2 數(shù)字格式化插值?
數(shù)字格式化插值可采用#{expr;format}形式來格式化數(shù)字,其中format可以是:?
mX:小數(shù)部分最小X位?
MX:小數(shù)部分最大X位?
如下面的例子:?
<#assign x=2.582/>?
<#assign y=4/>?
#{x; M2} <#-- 輸出2.58 -->?
#{y; M2} <#-- 輸出4 -->?
#{x; m2} <#-- 輸出2.6 -->?
#{y; m2} <#-- 輸出4.0 -->?
#{x; m1M2} <#-- 輸出2.58 -->?
#{x; m1M2} <#-- 輸出4.0 -->?
3, 表達式?
表達式是FreeMarker模板的核心功能,表達式放置在插值語法${}之中時,表明需要輸出表達式的值;表達式語法也可與FreeMarker 標(biāo)簽結(jié)合,用于控制輸出.實際上FreeMarker的表達式功能非常強大,它不僅支持直接指定值,輸出變量值,也支持字符串格式化輸出和集合訪問等功能.?
3.1 直接指定值?
使用直接指定值語法讓FreeMarker直接輸出插值中的值,而不是輸出變量值.直接指定值可以是字符串,數(shù)值,布爾值,集合和MAP對象.?
1,字符串?
直接指定字符串值使用單引號或雙引號限定,如果字符串值中包含特殊字符需要轉(zhuǎn)義,看下面的例子:?
${"我的文件保存在C:\\盤"}?
${'我名字是\"annlee\"'}?
輸出結(jié)果是:?
我的文件保存在C:\盤?
我名字是"annlee"?
FreeMarker支持如下轉(zhuǎn)義字符:?
\";雙引號(u0022)?
\';單引號(u0027)?
\\;反斜杠(u005C)?
\n;換行(u000A)?
\r;回車(u000D)?
\t;Tab(u0009)?
\b;退格鍵(u0008)?
\f;Form feed(u000C)?
\l;<?
\g;>?
\a;&?
\{;{?
\xCode;直接通過4位的16進制數(shù)來指定Unicode碼,輸出該unicode碼對應(yīng)的字符.?
如果某段文本中包含大量的特殊符號,FreeMarker提供了另一種特殊格式:可以在指定字符串內(nèi)容的引號前增加r標(biāo)記,在r標(biāo)記后的文件將會直接輸出.看如下代碼:?
${r"${foo}"}?
${r"C:\foo\bar"}?
輸出結(jié)果是:?
${foo}?
C:\foo\bar?
2,數(shù)值?
表達式中的數(shù)值直接輸出,不需要引號.小數(shù)點使用"."分隔,不能使用分組","符號.FreeMarker目前還不支持科學(xué)計數(shù)法,所以"1E3"是錯誤的.在FreeMarker表達式中使用數(shù)值需要注意以下幾點:?
1,數(shù)值不能省略小數(shù)點前面的0,所以".5"是錯誤的寫法?
2,數(shù)值8 , +8 , 8.00都是相同的?
3,布爾值?
直接使用true和false,不使用引號.?
4,集合?
集合以方括號包括,各集合元素之間以英文逗號","分隔,看如下的例子:?
<#list ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"] as x>?
${x}?
</#list>?
輸出結(jié)果是:?
星期一?
星期二?
星期三?
星期四?
星期五?
星期六?
星期天?
除此之外,集合元素也可以是表達式,例子如下:?
[2 + 2, [1, 2, 3, 4], "whatnot"]?
還可以使用數(shù)字范圍定義數(shù)字集合,如2..5等同于[2, 3, 4, 5],但是更有效率.注意,使用數(shù)字范圍來定義集合時無需使用方括號,數(shù)字范圍也支持反遞增的數(shù)字范圍,如5..2?
5,Map對象?
Map對象使用花括號包括,Map中的key-value對之間以英文冒號":"分隔,多組key-value對之間以英文逗號","分隔.下面是一個例子:?
{"語文":78, "數(shù)學(xué)":80}?
Map對象的key和value都是表達式,但是key必須是字符串?
3.2 輸出變量值?
FreeMarker的表達式輸出變量時,這些變量可以是頂層變量,也可以是Map對象中的變量,還可以是集合中的變量,并可以使用點(.)語法來訪問Java對象的屬性.下面分別討論這些情況?
1,頂層變量?
所謂頂層變量就是直接放在數(shù)據(jù)模型中的值,例如有如下數(shù)據(jù)模型:?
Map root = new HashMap();?? //創(chuàng)建數(shù)據(jù)模型?
root.put("name","annlee");?? //name是一個頂層變量?
對于頂層變量,直接使用${variableName}來輸出變量值,變量名只能是字母,數(shù)字,下劃線,$,@和#的組合,且不能以數(shù)字開頭號.為了輸出上面的name的值,可以使用如下語法:?
${name}?
2,輸出集合元素?
如果需要輸出集合元素,則可以根據(jù)集合元素的索引來輸出集合元素,集合元素的索引以方括號指定.假設(shè)有索引:?
["星期一","星期二","星期三","星期四","星期五","星期六","星期天"].該索引名為week,如果需要輸出星期三,則可以使用如下語法:?
${week[2]}?? //輸出第三個集合元素?
此外,FreeMarker還支持返回集合的子集合,如果需要返回集合的子集合,則可以使用如下語法:?
week[3..5]?? //返回week集合的子集合,子集合中的元素是week集合中的第4-6個元素?
3,輸出Map元素?
這里的Map對象可以是直接HashMap的實例,甚至包括JavaBean實例,對于JavaBean實例而言,我們一樣可以把其當(dāng)成屬性為key,屬性值為value的Map實例.為了輸出Map元素的值,可以使用點語法或方括號語法.假如有下面的數(shù)據(jù)模型:?
Map root = new HashMap();?
Book book = new Book();?
Author author = new Author();?
author.setName("annlee");?
author.setAddress("gz");?
book.setName("struts2");?
book.setAuthor(author);?
root.put("info","struts");?
root.put("book", book);?
為了訪問數(shù)據(jù)模型中名為struts2的書的作者的名字,可以使用如下語法:?
book.author.name??? //全部使用點語法?
book["author"].name?
book.author["name"]??? //混合使用點語法和方括號語法?
book["author"]["name"]?? //全部使用方括號語法?
使用點語法時,變量名字有頂層變量一樣的限制,但方括號語法沒有該限制,因為名字可以是任意表達式的結(jié)果.?
3.3, 字符串操作?
FreeMarker的表達式對字符串操作非常靈活,可以將字符串常量和變量連接起來,也可以返回字符串的子串等.?
字符串連接有兩種語法:?
1,使用${..}或#{..}在字符串常量部分插入表達式的值,從而完成字符串連接.?
2,直接使用連接運算符+來連接字符串?
例如有如下數(shù)據(jù)模型:?
Map root = new HashMap(); root.put("user","annlee");?
下面將user變量和常量連接起來:?
${"hello, ${user}!"}?? //使用第一種語法來連接?
${"hello, " + user + "!"} //使用+號來連接?
上面的輸出字符串都是hello,annlee!,可以看出這兩種語法的效果完全一樣.?
值得注意的是,${..}只能用于文本部分,不能用于表達式,下面的代碼是錯誤的:?
<#if ${isBig}>Wow!</#if>?
<#if "${isBig}">Wow!</#if>?
應(yīng)該寫成:<#if isBig>Wow!</#if>?
截取子串可以根據(jù)字符串的索引來進行,截取子串時如果只指定了一個索引值,則用于取得字符串中指定索引所對應(yīng)的字符;如果指定兩個索引值,則返回兩個索引中間的字符串子串.假如有如下數(shù)據(jù)模型:?
Map root = new HashMap(); root.put("book","struts2,freemarker");?
可以通過如下語法來截取子串:?
${book[0]}${book[4]}?? //結(jié)果是su?
${book[1..4]}???? //結(jié)果是tru?
3.4 集合連接運算符?
這里所說的集合運算符是將兩個集合連接成一個新的集合,連接集合的運算符是+,看如下的例子:?
<#list ["星期一","星期二","星期三"] + ["星期四","星期五","星期六","星期天"] as x>?
${x}?
</#list>?
輸出結(jié)果是:星期一 星期二 星期三 星期四 星期五 星期六 星期天?
3.5 Map連接運算符?
Map對象的連接運算符也是將兩個Map對象連接成一個新的Map對象,Map對象的連接運算符是+,如果兩個Map對象具有相同的key,則右邊的值替代左邊的值.看如下的例子:?
<#assign scores = {"語文":86,"數(shù)學(xué)":78} + {"數(shù)學(xué)":87,"Java":93}>?
語文成績是${scores.語文}?
數(shù)學(xué)成績是${scores.數(shù)學(xué)}?
Java成績是${scores.Java}?
輸出結(jié)果是:?
語文成績是86?
數(shù)學(xué)成績是87?
Java成績是93?
3.6 算術(shù)運算符?
FreeMarker表達式中完全支持算術(shù)運算,FreeMarker支持的算術(shù)運算符包括:+, - , * , / , % 看如下的代碼:?
<#assign x=5>?
${ x * x - 100 }?
${ x /2 }?
${ 12 %10 }?
輸出結(jié)果是:?
-75?? 2.5?? 2?
在表達式中使用算術(shù)運算符時要注意以下幾點:?
1,運算符兩邊的運算數(shù)字必須是數(shù)字?
2,使用+運算符時,如果一邊是數(shù)字,一邊是字符串,就會自動將數(shù)字轉(zhuǎn)換為字符串再連接,如:${3 + "5"},結(jié)果是:35?
使用內(nèi)建的int函數(shù)可對數(shù)值取整,如:?
<#assign x=5>?
${ (x/2)?int }?
${ 1.1?int }?
${ 1.999?int }?
${ -1.1?int }?
${ -1.999?int }?
結(jié)果是:2 1 1 -1 -1?
3.7 比較運算符?
表達式中支持的比較運算符有如下幾個:?
1,=或者==:判斷兩個值是否相等.?
2,!=:判斷兩個值是否不等.?
3,>或者gt:判斷左邊值是否大于右邊值?
4,>=或者gte:判斷左邊值是否大于等于右邊值?
5,<或者lt:判斷左邊值是否小于右邊值?
6,<=或者lte:判斷左邊值是否小于等于右邊值?
注意:=和!=可以用于字符串,數(shù)值和日期來比較是否相等,但=和!=兩邊必須是相同類型的值,否則會產(chǎn)生錯誤,而且FreeMarker是精確比較,"x","x ","X"是不等的.其它的運行符可以作用于數(shù)字和日期,但不能作用于字符串,大部分的時候,使用gt等字母運算符代替>會有更好的效果,因為 FreeMarker會把>解釋成FTL標(biāo)簽的結(jié)束字符,當(dāng)然,也可以使用括號來避免這種情況,如:<#if (x>y)>?
3.8 邏輯運算符?
邏輯運算符有如下幾個:?
邏輯與:&&?
邏輯或:||?
邏輯非:!?
邏輯運算符只能作用于布爾值,否則將產(chǎn)生錯誤?
3.9 內(nèi)建函數(shù)?
FreeMarker還提供了一些內(nèi)建函數(shù)來轉(zhuǎn)換輸出,可以在任何變量后緊跟?,?后緊跟內(nèi)建函數(shù),就可以通過內(nèi)建函數(shù)來輪換輸出變量.下面是常用的內(nèi)建的字符串函數(shù):?
html:對字符串進行HTML編碼?
cap_first:使字符串第一個字母大寫?
lower_case:將字符串轉(zhuǎn)換成小寫?
upper_case:將字符串轉(zhuǎn)換成大寫?
trim:去掉字符串前后的空白字符?
下面是集合的常用內(nèi)建函數(shù)?
size:獲取序列中元素的個數(shù)?
下面是數(shù)字值的常用內(nèi)建函數(shù)?
int:取得數(shù)字的整數(shù)部分,結(jié)果帶符號?
例如:?
<#assign test="Tom & Jerry">?
${test?html}?
${test?upper_case?html}?
結(jié)果是:Tom & Jerry?? TOM & JERRY?
3.10 空值處理運算符?
FreeMarker對空值的處理非常嚴(yán)格,FreeMarker的變量必須有值,沒有被賦值的變量就會拋出異常,因為FreeMarker未賦值的變量強制出錯可以杜絕很多潛在的錯誤,如缺失潛在的變量命名,或者其他變量錯誤.這里所說的空值,實際上也包括那些并不存在的變量,對于一個Java的 null值而言,我們認(rèn)為這個變量是存在的,只是它的值為null,但對于FreeMarker模板而言,它無法理解null值,null值和不存在的變量完全相同.?
為了處理缺失變量,FreeMarker提供了兩個運算符:?
!:指定缺失變量的默認(rèn)值?
??:判斷某個變量是否存在?
其中,!運算符的用法有如下兩種:?
variable!或variable!defaultValue,第一種用法不給缺失的變量指定默認(rèn)值,表明默認(rèn)值是空字符串,長度為0的集合,或者長度為0的Map對象.?
使用!指定默認(rèn)值時,并不要求默認(rèn)值的類型和變量類型相同.使用??運算符非常簡單,它總是返回一個布爾值,用法為:variable??,如果該變量存在,返回true,否則返回false?
3.11 運算符的優(yōu)先級?
FreeMarker中的運算符優(yōu)先級如下(由高到低排列):?
1,一元運算符:!?
2,內(nèi)建函數(shù):??
3,乘除法:*, / , %?
4,加減法:- , +?
5,比較:> , < , >= , <= (lt , lte , gt , gte)?
6,相等:== , = , !=?
7,邏輯與:&&?
8,邏輯或:||?
9,數(shù)字范圍:..?
實際上,我們在開發(fā)過程中應(yīng)該使用括號來嚴(yán)格區(qū)分,這樣的可讀性好,出錯少?
4 FreeMarker的常用指令?
FreeMarker的FTL指令也是模板的重要組成部分,這些指令可實現(xiàn)對數(shù)據(jù)模型所包含數(shù)據(jù)的撫今迭代,分支控制.除此之外,還有一些重要的功能,也是通過FTL指令來實現(xiàn)的.?
4.1 if指令?
這是一個典型的分支控制指令,該指令的作用完全類似于Java語言中的if,if指令的語法格式如下:?
<#if condition>...?
<#elseif condition>...?
<#elseif condition>...?
<#else> ...?
</#if>?
例子如下:?
<#assign age=23>?
<#if (age>60)>老年人?
<#elseif (age>40)>中年人?
<#elseif (age>20)>青年人?
<#else> 少年人?
</#if>?
輸出結(jié)果是:青年人?
上面的代碼中的邏輯表達式用括號括起來主要是因為里面有>符號,由于FreeMarker會將>符號當(dāng)成標(biāo)簽的結(jié)束字符,可能導(dǎo)致程序出錯,為了避免這種情況,我們應(yīng)該在凡是出現(xiàn)這些符號的地方都使用括號.?
4.2 switch , case , default , break指令?
這些指令顯然是分支指令,作用類似于Java的switch語句,switch指令的語法結(jié)構(gòu)如下:?
<#switch value>?
<#case refValue>...<#break>?
<#case refValue>...<#break>?
<#default>...?
</#switch>?
4.3 list, break指令?
list指令是一個迭代輸出指令,用于迭代輸出數(shù)據(jù)模型中的集合,list指令的語法格式如下:?
<#list sequence as item>?
...?
</#list>?
上面的語法格式中,sequence就是一個集合對象,也可以是一個表達式,但該表達式將返回一個集合對象,而item是一個任意的名字,就是被迭代輸出的集合元素.此外,迭代集合對象時,還包含兩個特殊的循環(huán)變量:?
item_index:當(dāng)前變量的索引值?
item_has_next:是否存在下一個對象?
也可以使用<#break>指令跳出迭代?
例子如下:?
<#list ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"] as x>?
${x_index + 1}.${x}<#if x_has_next>,</if>?
<#if x="星期四"><#break></#if>?
</#list>?
4.4 include指令?
include指令的作用類似于JSP的包含指令,用于包含指定頁.include指令的語法格式如下:?
<#include filename [options]>?
在上面的語法格式中,兩個參數(shù)的解釋如下:?
filename:該參數(shù)指定被包含的模板文件?
options:該參數(shù)可以省略,指定包含時的選項,包含encoding和parse兩個選項,其中encoding指定包含頁面時所用的解碼集,而parse指定被包含文件是否作為FTL文件來解析,如果省略了parse選項值,則該選項默認(rèn)是true.?
4.5 import指令?
該指令用于導(dǎo)入FreeMarker模板中的所有變量,并將該變量放置在指定的Map對象中,import指令的語法格式如下:?
<#import "/lib/common.ftl" as com>?
上面的代碼將導(dǎo)入/lib/common.ftl模板文件中的所有變量,交將這些變量放置在一個名為com的Map對象中.?
4.6 noparse指令?
noparse指令指定FreeMarker不處理該指定里包含的內(nèi)容,該指令的語法格式如下:?
<#noparse>...</#noparse>?
看如下的例子:?
<#noparse>?
<#list books as book>?
?? <tr><td>${book.name}<td>作者:${book.author}?
</#list>?
</#noparse>?
輸出如下:?
<#list books as book>?
?? <tr><td>${book.name}<td>作者:${book.author}?
</#list>?
4.7 escape , noescape指令?
escape指令導(dǎo)致body區(qū)的插值都會被自動加上escape表達式,但不會影響字符串內(nèi)的插值,只會影響到body內(nèi)出現(xiàn)的插值,使用escape指令的語法格式如下:?
<#escape identifier as expression>...?
<#noescape>...</#noescape>?
</#escape>?
看如下的代碼:?
<#escape x as x?html>?
First name:${firstName}?
Last name:${lastName}?
Maiden name:${maidenName}?
</#escape>?
上面的代碼等同于:?
First name:${firstName?html}?
Last name:${lastName?html}?
Maiden name:${maidenName?html}?
escape指令在解析模板時起作用而不是在運行時起作用,除此之外,escape指令也嵌套使用,子escape繼承父escape的規(guī)則,如下例子:?
<#escape x as x?html>?
Customer Name:${customerName}?
Items to ship;?
<#escape x as itemCodeToNameMap[x]>?
?? ${itemCode1}?
?? ${itemCode2}?
?? ${itemCode3}?
?? ${itemCode4}?
</#escape>?
</#escape>?
上面的代碼類似于:?
Customer Name:${customerName?html}?
Items to ship;?
${itemCodeToNameMap[itemCode1]?html}?
${itemCodeToNameMap[itemCode2]?html}?
${itemCodeToNameMap[itemCode3]?html}?
${itemCodeToNameMap[itemCode4]?html}?
對于放在escape指令中所有的插值而言,這此插值將被自動加上escape表達式,如果需要指定escape指令中某些插值無需添加escape表達式,則應(yīng)該使用noescape指令,放在noescape指令中的插值將不會添加escape表達式.?
4.8 assign指令?
assign指令在前面已經(jīng)使用了多次,它用于為該模板頁面創(chuàng)建或替換一個頂層變量,assign指令的用法有多種,包含創(chuàng)建或替換一個頂層變量, 或者創(chuàng)建或替換多個變量等,它的最簡單的語法如下:<#assign name=value [in namespacehash]>,這個用法用于指定一個名為name的變量,該變量的值為value,此外,FreeMarker允許在使用 assign指令里增加in子句,in子句用于將創(chuàng)建的name變量放入namespacehash命名空間中.?
assign指令還有如下用法:<#assign name1=value1 name2=value2 ... nameN=valueN [in namespacehash]>,這個語法可以同時創(chuàng)建或替換多個頂層變量,此外,還有一種復(fù)雜的用法,如果需要創(chuàng)建或替換的變量值是一個復(fù)雜的表達式,則可以使用如下語法格式:<#assign name [in namespacehash]>capture this</#assign>,在這個語法中,是指將assign指令的內(nèi)容賦值給name變量.如下例子:?
<#assign x>?
<#list ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"] as n>?
${n}?
</#list>?
</#assign>?
${x}?
上面的代碼將產(chǎn)生如下輸出:星期一 星期二 星期三 星期四 星期五 星期六 星期天?
雖然assign指定了這種復(fù)雜變量值的用法,但是我們也不要濫用這種用法,如下例子:<#assign x>Hello ${user}!</#assign>,以上代碼改為如下寫法更合適:<#assign x="Hello ${user}!">?
4.9 setting指令?
該指令用于設(shè)置FreeMarker的運行環(huán)境,該指令的語法格式如下:<#setting name=value>,在這個格式中,name的取值范圍包含如下幾個:?
locale:該選項指定該模板所用的國家/語言選項?
number_format:指定格式化輸出數(shù)字的格式?
boolean_format:指定兩個布爾值的語法格式,默認(rèn)值是true,false?
date_format,time_format,datetime_format:指定格式化輸出日期的格式?
time_zone:設(shè)置格式化輸出日期時所使用的時區(qū)?
4.10 macro , nested , return指令?
macro可以用于實現(xiàn)自定義指令,通過使用自定義指令,可以將一段模板片段定義成一個用戶指令,使用macro指令的語法格式如下:?
<#macro name param1 param2 ... paramN>?
...?
<#nested loopvar1, loopvar2, ..., loopvarN>?
...?
<#return>?
...?
</#macro>?
在上面的格式片段中,包含了如下幾個部分:?
name:name屬性指定的是該自定義指令的名字,使用自定義指令時可以傳入多個參數(shù)?
paramX:該屬性就是指定使用自定義指令時報參數(shù),使用該自定義指令時,必須為這些參數(shù)傳入值?
nested指令:nested標(biāo)簽輸出使用自定義指令時的中間部分?
nested指令中的循環(huán)變量:這此循環(huán)變量將由macro定義部分指定,傳給使用標(biāo)簽的模板?
return指令:該指令可用于隨時結(jié)束該自定義指令.?
看如下的例子:?
<#macro book>?? //定義一個自定義指令?
j2ee?
</#macro>?
<@book />??? //使用剛才定義的指令?
上面的代碼輸出結(jié)果為:j2ee?
在上面的代碼中,可能很難看出自定義標(biāo)簽的用處,因為我們定義的book指令所包含的內(nèi)容非常簡單,實際上,自定義標(biāo)簽可包含非常多的內(nèi)容,從而可以實現(xiàn)更好的代碼復(fù)用.此外,還可以在定義自定義指令時,為自定義指令指定參數(shù),看如下代碼:?
<#macro book booklist>???? //定義一個自定義指令booklist是參數(shù)?
<#list booklist as book>?
?? ${book}?
</#list>?
</#macro>?
<@book booklist=["spring","j2ee"] />?? //使用剛剛定義的指令?
上面的代碼為book指令傳入了一個參數(shù)值,上面的代碼的輸出結(jié)果為:spring j2ee?
不僅如此,還可以在自定義指令時使用nested指令來輸出自定義指令的中間部分,看如下例子:?
<#macro page title>?
<html>?
<head>?
?? <title>FreeMarker示例頁面 - ${title?html}</title>?
</head>?
<body>?
?? <h1>${title?html}</h1>?
?? <#nested>????? //用于引入用戶自定義指令的標(biāo)簽體?
</body>?
</html>?
</#macro>?
上面的代碼將一個HTML頁面模板定義成一個page指令,則可以在其他頁面中如此page指令:?
<#import "/common.ftl" as com>???? //假設(shè)上面的模板頁面名為common.ftl,導(dǎo)入頁面?
<@com.page title="book list">?
<u1>?
<li>spring</li>?
<li>j2ee</li>?
</ul>?
</@com.page>?
從上面的例子可以看出,使用macro和nested指令可以非常容易地實現(xiàn)頁面裝飾效果,此外,還可以在使用nested指令時,指定一個或多個循環(huán)變量,看如下代碼:?
<#macro book>?
<#nested 1>????? //使用book指令時指定了一個循環(huán)變量值?
<#nested 2>?
</#macro>?
<@book ;x> ${x} .圖書</@book>?
當(dāng)使用nested指令傳入變量值時,在使用該自定義指令時,就需要使用一個占位符(如book指令后的;x).上面的代碼輸出文本如下:?
1 .圖書??? 2 .圖書?
在nested指令中使用循環(huán)變量時,可以使用多個循環(huán)變量,看如下代碼:?
<#macro repeat count>?
<#list 1..count as x>???? //使用nested指令時指定了三個循環(huán)變量?
?? <#nested x, x/2, x==count>?
</#list>?
</#macro>?
<@repeat count=4 ; c halfc last>?
${c}. ${halfc}<#if last> Last! </#if>?
</@repeat>?
上面的輸出結(jié)果為:?
1. 0.5?? 2. 1?? 3. 1.5?? 4. 2 Last;?
return指令用于結(jié)束macro指令,一旦在macro指令中執(zhí)行了return指令,則FreeMarker不會繼續(xù)處理macro指令里的內(nèi)容,看如下代碼:?
<#macro book>?
spring?
<#return>?
j2ee?
</#macro>?
<@book />?
上面的代碼輸出:spring,而j2ee位于return指令之后,不會輸出.?
if, else, elseif?
switch, case, default, break?
list, break?
include?
Import?
compress?
escape, noescape?
assign?
global?
setting?
macro, nested, return?
t, lt, rt?
3一些常用方法或注意事項?
表達式轉(zhuǎn)換類?
數(shù)字循環(huán)?
對浮點取整數(shù)?
給變量默認(rèn)值?
判斷對象是不是null?
常用格式化日期?
添加全局共享變量數(shù)據(jù)模型?
直接調(diào)用java對象的方法?
字符串處理(內(nèi)置方法)?
在模板里對sequences和hashes初始化?
注釋標(biāo)志?
sequences內(nèi)置方法?
hashes內(nèi)置方法?
4 freemarker在web開發(fā)中注意事項?
web中常用的幾個對象?
view中值的搜索順序?
在模板里ftl里使用標(biāo)簽?
如何初始化共享變量?
與webwork整合配置?
5高級方法?
自定義方法?
自定義 Transforms?
?????????????????????????????????
1概念?
最常用的3個概念?
sequence? 序列,對應(yīng)java里的list、數(shù)組等非鍵值對的集合?
hash????? 鍵值對的集合?
namespace 對一個ftl文件的引用,利用這個名字可以訪問到該ftl文件的資源?
2指令?
if, else, elseif?
語法?
<#if condition>?
? ...?
<#elseif condition2>?
? ...?
<#elseif condition3>?
? ...?
...?
<#else>?
? ...?
</#if>?
用例?
<#if x = 1>?
? x is 1?
</#if>?
<#if x = 1>?
? x is 1?
<#else>?
? x is not 1?
</#if>?
switch, case, default, break?
語法?
<#switch value>?
? <#case refValue1>?
??? ...?
??? <#break>?
? <#case refValue2>?
??? ...?
??? <#break>?
? ...?
? <#case refValueN>?
??? ...?
??? <#break>?
? <#default>?
??? ...?
</#switch>?
用例?
字符串?
<#switch being.size>?
? <#case "small">?
???? This will be processed if it is small?
???? <#break>?
? <#case "medium">?
???? This will be processed if it is medium?
???? <#break>?
? <#case "large">?
???? This will be processed if it is large?
???? <#break>?
? <#default>?
???? This will be processed if it is neither?
</#switch>?
數(shù)字?
<#switch x>?
? <#case x = 1>?
??? 1?
? <#case x = 2>?
??? 2?
? <#default>?
??? d?
</#switch>?
如果x=1 輸出 1 2, x=2輸出 2, x=3 輸出d?
list, break?
語法?
<#list sequence as item>?
...?
<#if item = "spring"><#break></#if>?
...?
</#list>?
關(guān)鍵字?
item_index:是list當(dāng)前值的下標(biāo)?
item_has_next:判斷l(xiāng)ist是否還有值?
用例?
<#assign seq = ["winter", "spring", "summer", "autumn"]>?
<#list seq as x>?
? ${x_index + 1}. ${x}<#if x_has_next>,</#if>?
</#list>?
輸出?
? 1. winter,?
? 2. spring,?
? 3. summer,?
? 4. autumn??
include?
語法?
<#include filename>?
or?
<#include filename options>?
options包含兩個屬性?
encoding=”GBK” 編碼格式?
parse=true 是否作為ftl語法解析,默認(rèn)是true,false就是以文本方式引入.注意在ftl文件里布爾值都是直接賦值的如parse=true,而不是parse=”true”?
用例?
/common/copyright.ftl包含內(nèi)容?
Copyright 2001-2002 ${me}<br>?
All rights reserved.?
模板文件?
<#assign me = "Juila Smith">?
<h1>Some test</h1>?
<p>Yeah.?
<hr>?
<#include "/common/copyright.ftl" encoding=”GBK”>?
輸出結(jié)果?
<h1>Some test</h1>?
<p>Yeah.?
<hr>?
Copyright 2001-2002 Juila Smith?
All rights reserved.?
Import?
語法?
<#import path as hash>?
類似于java里的import,它導(dǎo)入文件,然后就可以在當(dāng)前文件里使用被導(dǎo)入文件里的宏組件?
用例?
假設(shè)mylib.ftl里定義了宏copyright那么我們在其他模板頁面里可以這樣使用?
<#import "/libs/mylib.ftl" as my>?
<@my.copyright date="1999-2002"/>?
"my"在freemarker里被稱作namespace?
compress?
語法?
<#compress>?
? ...?
</#compress>?
用來壓縮空白空間和空白的行?
用例?
<#assign x = "??? moo? \n\n?? ">?
(<#compress>?
? 1 2? 3?? 4??? 5?
? ${moo}?
? test only?
? I said, test only?
</#compress>)?
輸出?
(1 2 3 4 5?
moo?
test only?
I said, test only)?
escape, noescape?
語法?
<#escape identifier as expression>?
? ...?
? <#noescape>...</#noescape>?
? ...?
</#escape>?
用例?
主要使用在相似的字符串變量輸出,比如某一個模塊的所有字符串輸出都必須是html安全的,這個時候就可以使用該表達式?
<#escape x as x?html>?
? First name: ${firstName}?
? <#noescape>Last name: ${lastName}</#noescape>?
? Maiden name: ${maidenName}?
</#escape>?
相同表達式?
? First name: ${firstName?html}?
? Last name: ${lastName }?
? Maiden name: ${maidenName?html}?
assign?
語法?
<#assign name=value>?
or?
<#assign name1=value1 name2=value2 ... nameN=valueN>?
or?
<#assign same as above... in namespacehash>?
or?
<#assign name>?
? capture this?
</#assign>?
or?
<#assign name in namespacehash>?
? capture this?
</#assign>?
用例?
生成變量,并且給變量賦值?
給seasons賦予序列值?
<#assign seasons = ["winter", "spring", "summer", "autumn"]>?
給變量test加1?
<#assign test = test + 1>?
給my namespage 賦予一個變量bgColor,下面可以通過my.bgColor來訪問這個變量?
<#import "/mylib.ftl" as my>?
<#assign bgColor="red" in my>?
將一段輸出的文本作為變量保存在x里?
下面的陰影部分輸出的文本將被賦值給x?
<#assign x>?
? <#list 1..3 as n>?
??? ${n} <@myMacro />?
? </#list>?
</#assign>?
Number of words: ${x?word_list?size}?
${x}?
<#assign x>Hello ${user}!</#assign>???? error?
<#assign x=” Hello ${user}!”>???????? true?
同時也支持中文賦值,如:?
<#assign 語法>?
? java?
</#assign>?
${語法}?
打印輸出:?
java?
global?
語法?
<#global name=value>?
or?
<#global name1=value1 name2=value2 ... nameN=valueN>?
or?
<#global name>?
? capture this?
</#global>?
全局賦值語法,利用這個語法給變量賦值,那么這個變量在所有的namespace中是可見的,如果這個變量被當(dāng)前的assign語法覆蓋如<#global x=2> <#assign x=1> 在當(dāng)前頁面里x=2將被隱藏,或者通過${.global.x}來訪問?
setting?
語法?
<#setting name=value>?
用來設(shè)置整個系統(tǒng)的一個環(huán)境?
locale?
number_format?
boolean_format?
date_format, time_format, datetime_format?
time_zone?
classic_compatible?
用例?
假如當(dāng)前是匈牙利的設(shè)置,然后修改成美國?
${1.2}?
<#setting locale="en_US">?
${1.2}?
輸出?
1,2?
1.2?
因為匈牙利是采用“,”作為十進制的分隔符,美國是用“.”?
macro, nested, return?
語法?
<#macro name param1 param2 ... paramN>?
? ...?
? <#nested loopvar1, loopvar2, ..., loopvarN>?
? ...?
? <#return>?
? ...?
</#macro>?
用例?
<#macro test foo bar="Bar" baaz=-1>?
? Test text, and the params: ${foo}, ${bar}, ${baaz}?
</#macro>?
<@test foo="a" bar="b" baaz=5*5-2/>?
<@test foo="a" bar="b"/>?
<@test foo="a" baaz=5*5-2/>?
<@test foo="a"/>?
輸出?
? Test text, and the params: a, b, 23?
? Test text, and the params: a, b, -1?
? Test text, and the params: a, Bar, 23?
? Test text, and the params: a, Bar, -1?
定義循環(huán)輸出的宏?
<#macro list title items>?
? <p>${title?cap_first}:?
? <ul>?
??? <#list items as x>?
????? <li>${x?cap_first}?
??? </#list>?
? </ul>?
</#macro>?
<@list items=["mouse", "elephant", "python"] title="Animals"/>?
輸出結(jié)果?
<p>Animals:?
? <ul>?
????? <li>Mouse?
????? <li>Elephant?
????? <li>Python?
? </ul>?
包含body的宏?
<#macro repeat count>?
? <#list 1..count as x>?
??? <#nested x, x/2, x==count>?
? </#list>?
</#macro>?
<@repeat count=4 ; c halfc last>?
? ${c}. ${halfc}<#if last> Last!</#if>?
</@repeat>?
輸出?
1. 0.5?
? 2. 1?
? 3. 1.5?
? 4. 2 Last!?
t, lt, rt?
語法?
<#t> 去掉左右空白和回車換行?
<#lt>去掉左邊空白和回車換行?
<#rt>去掉右邊空白和回車換行?
<#nt>取消上面的效果?
3一些常用方法或注意事項?
表達式轉(zhuǎn)換類?
${expression}計算expression并輸出?
#{ expression }數(shù)字計算#{ expression ;format}安格式輸出數(shù)字format為M和m?
M表示小數(shù)點后最多的位數(shù),m表示小數(shù)點后最少的位數(shù)如#{121.2322;m2M2}輸出121.23?
數(shù)字循環(huán)?
1..5 表示從1到5,原型number..number?
對浮點取整數(shù)?
${123.23?int} 輸出123?
給變量默認(rèn)值?
${var?default(“hello world<br>”)?html}如果var is null那么將會被hello world<br>替代?
判斷對象是不是null?
??? <#if mouse?exists>?
????? Mouse found?
<#else>?
也可以直接${mouse?if_exists})輸出布爾形?
常用格式化日期?
openingTime必須是Date型,詳細查看freemarker文檔 Reference->build-in referece->build-in for date?
${openingTime?date}?
${openingTime?date_time}?
${openingTime?time}?
添加全局共享變量數(shù)據(jù)模型?
在代碼里的實現(xiàn)?
??? cfg = Configuration.getDefaultConfiguration();?
cfg.setSharedVariable("global", "you good");?
頁面實現(xiàn)可以通過global指令,具體查看指令里的global部分?
直接調(diào)用java對象的方法?
${object.methed(args)}?
字符串處理(內(nèi)置方法)?
html安全輸出?
“abc<table>sdfsf”?html?
返回安全的html輸出,替換掉html代碼?
xml安全輸出?
var?xml??
substring的用法?
<#assign user=”hello jeen”>?
${user[0]}${user[4]}?
${user[1..4]}?
輸出 :?
ho?
ello?
類似String.split的用法?
“abc;def;ghi”?split(“;”)返回sequence?
將字符串按空格轉(zhuǎn)化成sequence,然后取sequence的長度?
???? var?word_list? 效果同 var?split(“ ”)?
var?word_list?size?
取得字符串長度?
var?length?
大寫輸出字符?
var?upper_case?
小寫輸出字符?
var?lower_case?
首字符大寫?
var?cap_first?
首字符小寫?
var?uncap_first?
去掉字符串前后空格?
var?trim?
每個單詞的首字符大寫?
var?capitalize?
類似String.indexof:?
“babcdabcd”?index_of(“abc”) 返回1?
“babcdabcd”?index_of(“abc”,2) 返回5?
類似String.lastIndexOf?
last_index_of和String.lastIndexOf類似,同上?
下面兩個可能在代碼生成的時候使用(在引號前加”\”)?
j_string: 在字符串引號前加”\”?
<#assign beanName = 'The "foo" bean.'>?
String BEAN_NAME = "${beanName?j_string}";?
打印輸出:?
String BEAN_NAME = "The \"foo\" bean.";?
js_string:?
<#assign user = "Big Joe's \"right hand\".">?
<script>?
? alert("Welcome ${user}!");?
</script>?
打印輸出?
alert("Welcome Big Joe\'s \"right hand\"!");?
替換字符串 replace?
${s?replace(‘ba’, ‘XY’ )}?
${s?replace(‘ba’, ‘XY’ , ‘規(guī)則參數(shù)’)}將s里的所有的ba替換成xy 規(guī)則參數(shù)包含: i r m s c f 具體含義如下:?
· i: 大小寫不區(qū)分.?
· f: 只替換第一個出現(xiàn)被替換字符串的字符串?
· r:? XY是正則表達式?
· m: Multi-line mode for regular expressions. In multi-line mode the expressions ^ and $ match just after or just before, respectively, a line terminator or the end of the string. By default these expressions only match at the beginning and the end of the entire string.?
· s: Enables dotall mode for regular expressions (same as Perl singe-line mode). In dotall mode, the expression . matches any character, including a line terminator. By default this expression does not match line terminators.?
· c: Permits whitespace and comments in regular expressions.?
在模板里對sequences和hashes初始化?
sequences?
1. [“you”,”me”,”he”]?
2. 1..100?
3. [ {“Akey”:”Avalue”},{“Akey1”:”Avalue1”},?
{“Bkey”:”Bvalue”},{“Bkey1”:”Bvalue1”},?
]?
hashes????? {“you”:”a”,”me”:”b”,”he”:”c”}?
注釋標(biāo)志?
<#--?
這里是注釋?
-->?
舊版本的freemarker采用的是<#comment> 注釋 </#comment>方法?
sequences內(nèi)置方法?
sequence?first?
返回sequence的第一個值;前提條件sequence不能是null?
sequence?last?
返回sequence最后一個值?
sequence?reverse?
反轉(zhuǎn)sequence的值?
sequence?size?
返回sequence的大小?
sequence?sort?
對sequence按里面的對象toString()的結(jié)果進行排序?
sequence?sort_by(value)?
對sequence 按里面的對象的屬性value進行排序?
如: sequence里面放入的是10 個user對象,user對象里面包含name,age等屬性?
sequence?sort_by(name) 表示所有的user按user.name進行排序?
hashes內(nèi)置方法?
hash?keys?
返回hash里的所有keys, 返回結(jié)果類型sequence?
hash?values?
返回hash里的所有value, 返回結(jié)果類型sequence?
4 freemarker在web開發(fā)中注意事項?
freemarker與webwork整合?
web中常用的幾個對象?
Freemarker的ftl文件中直接使用內(nèi)部對象:?
${Request ["a"]}?
${RequestParameters["a"]}?
${Session ["a"]}?
${Application ["a"]}?
${JspTaglibs ["a"]}?
與webwork整合之后 通過配置的servlet 已經(jīng)把request,session等對象置入了數(shù)據(jù)模型中?
在view中存在下面的對象?
? 我們可以在ftl中${req}來打印req對象?
· req - the current HttpServletRequest?
· res - the current HttpServletResponse?
· stack - the current OgnlValueStack?
· ognl - the OgnlTool instance?
· webwork - an instance of FreemarkerWebWorkUtil?
· action - the current WebWork action?
· exception - optional the Exception instance, if the view is a JSP exception or Servlet exception view?
view中值的搜索順序?
${name}將會以下面的順序查找name值?
· freemarker variables?
· value stack?
· request attributes?
· session attributes?
· servlet context attributes?
在模板里ftl里使用標(biāo)簽?
注意,如果標(biāo)簽的屬性值是數(shù)字,那么必須采用nubmer=123方式給屬性賦值?
JSP頁面?
<%@page contentType="text/html;charset=ISO-8859-2" language="java"%>?
<%@taglib uri="/WEB-INF/struts-html.tld" prefix="html"%>?
<%@taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%>?
<html>?
? <body>?
??? <h1><bean:message key="welcome.title"/></h1>?
??? <html:errors/>?
??? <html:form action="/query">?
????? Keyword: <html:text property="keyword"/><br>?
????? Exclude: <html:text property="exclude"/><br>?
????? <html:submit value="Send"/>?
??? </html:form>?
? </body>?
</html>?
模板ftl頁面?
<#assign html=JspTaglibs["/WEB-INF/struts-html.tld"]>?
<#assign bean=JspTaglibs["/WEB-INF/struts-bean.tld"]>?
<html>?
? <body>?
??? <h1><@bean.message key="welcome.title"/></h1>?
??? <@html.errors/>?
??? <@html.form action="/query">?
????? Keyword: <@html.text property="keyword"/><br>?
????? Exclude: <@html.text property="exclude"/><br>?
????? <@html.submit value="Send"/>?
??? </@html.form>?
? </body>?
</html>?
如何初始化共享變量?
1. 初始化全局共享數(shù)據(jù)模型?
freemark在web上使用的時候?qū)蚕頂?shù)據(jù)的初始化支持的不夠,不能在配置初始化的時候?qū)崿F(xiàn),而必須通過ftl文件來初始化全局變量。這是不能滿主需求的,我們需要在servlet init的時候留出一個接口來初始化系統(tǒng)的共享數(shù)據(jù)?
具體到和webwork整合,因為本身webwork提供了整合servlet,如果要增加全局共享變量,可以通過修改 com.opensymphony.webwork.views.freemarker.FreemarkerServlet來實現(xiàn),我們可以在這個 servlet初始化的時候來初始化全局共享變量?
與webwork整合配置?
配置web.xml?
<servlet>?
??? <servlet-name>freemarker</servlet-name>?
??? <servlet-class>com.opensymphony.webwork.views.freemarker.FreemarkerServlet</servlet-class>?
??? <init-param>?
????? <param-name>TemplatePath</param-name>?
<param-value>/</param-value>?
<!—模板載入文件夾,這里相對context root,遞歸獲取該文件夾下的所有模板-->?
??? </init-param>?
??? <init-param>?
????? <param-name>NoCache</param-name> <!—是否對模板緩存-->?
????? <param-value>true</param-value>?
??? </init-param>?
??? <init-param>?
????? <param-name>ContentType</param-name>?
????? <param-value>text/html</param-value>?
??? </init-param>?
??? <init-param>?
<param-name>template_update_delay</param-name>?
<!—模板更新時間,0表示每次都更新,這個適合開發(fā)時候-->?
????? <param-value>0</param-value>?
??? </init-param>?
??? <init-param>?
????? <param-name>default_encoding</param-name>?
????? <param-value>GBK</param-value>?
??? </init-param>?
??? <init-param>?
????? <param-name>number_format</param-name>?
????? <param-value>0.##########</param-value><!—數(shù)字顯示格式-->?
??? </init-param>?
??? <load-on-startup>1</load-on-startup>?
? </servlet>?
? <servlet-mapping>?
??? <servlet-name>freemarker</servlet-name>?
??? <url-pattern>*.ftl</url-pattern>?
? </servlet-mapping>?
5高級方法?
自定義方法?
${timer("yyyy-MM-dd H:mm:ss", x)}?
${timer("yyyy-MM-dd ", x)}?
在模板中除了可以通過對象來調(diào)用方法外(${object.methed(args)})也可以直接調(diào)用java實現(xiàn)的方法,java類必須實現(xiàn)接口TemplateMethodModel的方法exec(List args). 下面以把毫秒的時間轉(zhuǎn)換成按格式輸出的時間為例子?
public class LongToDate implements TemplateMethodModel {?
???
public TemplateModel exec(List args) throws TemplateModelException {?
SimpleDateFormat mydate = new SimpleDateFormat((String) args.get(0)));?
??????? return mydate.format(new Date(Long.parseLong((String)args.get(1)));?
??? }?
}?
將LongToDate對象放入到數(shù)據(jù)模型中?
root.put("timer", new IndexOfMethod());?
ftl模板里使用?
<#assign x = "123112455445">?
${timer("yyyy-MM-dd H:mm:ss", x)}?
${timer("yyyy-MM-dd ", x)}?
輸出?
2001-10-12 5:21:12?
2001-10-12?
自定義 Transforms?
實現(xiàn)自定義的<@transform>文本或表達式</@transform>的功能,允許對中間的最終文本進行解析轉(zhuǎn)換?
例子:實現(xiàn)<@upcase>str</@upcase> 將str轉(zhuǎn)換成STR 的功能?
代碼如下:?
import java.io.*;?
import java.util.*;?
import freemarker.template.TemplateTransformModel;?
class UpperCaseTransform implements TemplateTransformModel {?
??? public Writer getWriter(Writer out, Map args) {?
??????? return new UpperCaseWriter(out);?
??? }?
??? private class UpperCaseWriter extends Writer {?
??????
??????? private Writer out;?
??????????
??????? UpperCaseWriter (Writer out) {?
??????????? this.out = out;?
??????? }?
??????? public void write(char[] cbuf, int off, int len)?
??????????????? throws IOException {?
??????????? out.write(new String(cbuf, off, len).toUpperCase());?
??????? }?
??????? public void flush() throws IOException {?
??????????? out.flush();?
??????? }?
??????? public void close() {?
??????? }?
??? }?
}?
然后將此對象put到數(shù)據(jù)模型中?
root.put("upcase", new UpperCaseTransform());?
在view(ftl)頁面中可以如下方式使用?
<@upcase>?
hello world?
</@upcase>?
打印輸出:?
HELLO WORLD
轉(zhuǎn)載于:https://www.cnblogs.com/yangzhilong/p/4360626.html
總結(jié)
以上是生活随笔為你收集整理的freemarker入门教程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 通过代码来调用log4net写日志
- 下一篇: 关于人吃苹果的设计