1,截取字元串
有的時候我們在頁面中不需要顯示那麼長的字元串,比如新聞标題,這樣用下面的例子就可以自定義顯示的長度
< lt. <= lte. > gt. >= gte
<#if jstbqkVO.gzdd?length lt 8>
<a href>${jstbqkVO.gzdd?default("")}</a>
<#else>
<a href title="${jstbqkVO.gzdd}">${jstbqkVO.gzdd[0..3]?default("")}...</a>
</#if>
意思就是如果這個字元串的長度小于8,那麼就正常顯示,反之則取4位
2.連接配接字元串
${"Hello," + user + "!"} //輸出結果為:hello,gs!
3,日期格式和boolean 類型,轉化為string類型
例子2:
${lastUpdate?string("yyyy-MM-dd HH:mm:ss zzzz")}
${lastUpdate?string("EEE,MMM d, ''yy")}
${.................("EEEE,MMM dd,yyyy, hh:mm:ss a '('zzz')'")}
輸出結果如下:
2003-04-08 21:24:44 Pacific Daylight Time
Tue,Apr 8,'03
Tuesday,April 08,2003,09:24:44 PM (PDT)
例子3:
<#assign foo=true/>
${foo?string("yes","no")} //輸出結果:yes
4,排序:
1.升序.sort_by()
<#list list?sort_by("字段") as x>
</#list>
2.降序.sort_by()?reverse
<#list list?sort_by("字段")?reverse as x>
5去空格:
${xx?trim}
6數值精度控制
mX:小數部分最小X位。
MX:小數部分最大X位。
例子:
<#assign x=2.582/>
<#assign y=4/>
#{x; M2} //2.58
#{y; M2} //4
#{x; m1M2} //2.58
#{y; m1M2} //4.0
7特殊字元串的轉義
\":雙引号 \\:反斜杠 \r:回車 \b:倒退鍵
\':單引号 \n:換行 \t:Tab \f:Form feed
\l:< \g:> \a:& \{:{
\xCode:直接通過4位的十六進制數來指定Unicode碼
,輸出改Unicode對應的字元。
* 所謂頂層變量就是直接放在資料模型中的值。
Map root = new HashMap();
root.put("name","yeeku"); //name是一個頂層對象
* 對于頂層變量,直接使用${variableName}來輸出變量值
* 集合連接配接運算是将兩個集合連接配接成一個新的集合,連接配接集合的運算符是'+'.
<#list ["一","二","三"] + ["四","五","六"] as x>
${x}
</#list>
//輸出結果如下:
一二三四五六
* 取整運算
<#assign x=5>
${(x/2)?>int} //2
${1.1?int} //1
${1.999?int} //1
${-1.1?int} //-1
=(==) :判斷兩個值是否相等
!= :............不相等
>(gt) :判斷左邊是否大于右邊
>=(gte) :.....
<(lt) :.....
<=(lte) :.....
12 邏輯運算符
* 邏輯運算符隻能作用于布爾值,否則将産生錯誤.
邏輯與:&&
邏輯或:||
邏輯非:!
13 内置函數
html:字元串中所有的特殊HTML字元都需要用實體引用來代替(比如<代替&lt;)
cap_first:字元串的第一個字母變為大寫形式
lower_case:字元串的小寫形式
upper_case:字元串的大寫形式
trim:去掉字元串首尾的空格
序列使用的内建函數:
size:序列中元素的個數
數字使用的内建函數:
int:數字的整數部分(比如-1.9?int就是-1)9>.空值運算符
length:字元串的長度
string :把其他格式的資料,轉化為string類型
例:
${test?html}
${test?upper_case?html}
假設字元串test存儲”Tom & Jerry”,那麼輸出為:
Tom &amp; Jerry
TOM &amp; JERRY
${seasons?size}
${seasons[1]?cap_first}
${"horse"?cap_first}
假設seasons存儲了序列"winter", "spring", "summer", "autumn",那麼上面的輸出将會是:
4
Spring
Horse
14.運算符優先級
* 推薦使用括号來決定運算優先級.
1>.一進制運算符: !
2>.内建函數 : ?
3>.乘除法 : *,/,%
4>.加減法 : +,-
5>.比較 : <,>,<=,>=(lt,lte,gt,gte)
6>.相等 : ==(=),!=
7>.邏輯與 : &&
8>.邏輯或 : ||
9>.數字範圍 : ..
15,freemarker判斷傳回值是否為空,null的方法
對于null,或者miss value,freemarker會報錯
!:default value operator,文法結構為:unsafe_expr!default_expr,比如 ${mouse!"No mouse."} 當mouse不存在時,傳回default value;
(product.color)!"red" 這種方式,能夠處理product或者color為miss value的情況;
而product.color!"red"将隻處理color為miss value的情況
??: Missing value test operator ,測試是否為missing value
unsafe_expr?? :product.color??将隻測試color是否為null
(unsafe_expr)??:(product.color)??将測試product和color是否存在null
?exists:舊版本的用法
比如:<#if mouse??>
Mouse found
<#else>
No mouse found
Creating mouse...
<#assign mouse = "Jerry">
<#if mouse??>
FreeMarker的常用指令
<#if condifition>
...
<#elseif condifition>
<#else>
</#if>
<#switch value>
<#case refValue1>
...
<#break>
<#case refValue2>
<#default>
</#switch>
<#list sequence as item>
</#list>
* item_index :目前變量的索引值.
* item_has_next :是否存在下一個對象.
<#list ["星期一","星期二","星期三","星期四","星期五","星期六"] as x>
${x_index + 1}.${x}
<#if x_has_next>,</#if>
<#if x="星期四"><#break></#if>
輸出結果:
1.星期一,
2.星期二,
3.星期三,
4.興趣四,
4>.include指令
:用于指定包含指定頁面.
<#include filename [options]>
* filename: 該參數指定被包含的模闆檔案.
* options : 該參數可以被省略,指定包含時的選項,包含encoding和parase兩個選項.
<#import path as mapObject>
* path :指定要被導入的模闆檔案.
* mapObject :是一個Map對象.
意思:将path路徑中的變量都放在mapObject中.
例子:<#import "/lib/common.ftl" as com>
noparse指令指定FreeMarker不處理該指令裡包含的内容.
<#noparse>...</#noparse>
* escape:該指令導緻body區的插值都會被自動加上escape表達式.
* escape指令解析模闆時起作用,而不是在運作時起作用.
* escape指令也嵌套使用,子escape繼承父escape的規則.
* 如果需要指定某些插值無需添加escape表達式,則應該使用noescape指令.
<#escape identifier as expression>
<#noescape>...</#noescape>
</#escape>
* 它用于為該模闆頁面建立或替換一個(頂層)或多個變量.
第一種用法:<#assign name="value" [in namespacehash]>
in子句用于将建立的name變量放入namespacehash命名空間中.
第二種用法:<#assign name1=value1 name2=value2 ... nameN=valueN [in namespacehash]>
第三種用法: 是指将assign指令的内容指派給name變量.
<#assign name [in namespacehash]>
capture this
</#assign>
例子:
<#assign x>
<#list ["一","二","三"] as n>
${n}
</#list>
</#assign>
${x}
補充.global指令,全局變量指派
:該指令用于設定FreeMarker的運作環境.
<#setting name=value>
name的取值範圍如下:
locale:該指令指定該模闆所使用的國家語言/語言選項.
number_format:該指令指定格式化輸出數字的選項.
boolean_format:該指令指令兩個布爾值的文法格式,預設值是"false".
date_format、time_format、datetime_format:格式化輸出日期的格式.
time_zone: 設定格式化輸出日期時所使用的時區.
宏和變換器變量是兩種不同類型的使用者自定義指令,他們的差別是:
宏可以在模闆中用macro指令來定義
變換器是在模闆外由程式定義
1、宏:和某個變量關聯的模闆片段,以便在模闆中通過使用者自定義指令使用該變量
1-1、基本用法:
例如:
<#macro greet>
<font size="+2"> Hello JOE!</font>
</#macro>
使用時:
<@greet></@greet>
如果沒有體内容也可以用
<@greet />
1-2、變量:
1)、可以在宏定義之後定義參數,宏參數是局部變量,隻在宏定義中有效。如:
<#macro greet person>
<font size="+2"> Hello ${person}!</font>
<@greet person="emma"> and <@greet person="LEO">
輸出為:
<font size="+2"> Hello emma!</font>
<font size="+2"> Hello LEO!</font>
注意:宏的參數是FTL表達式,是以,person=emma和上面的例子中具有不同的意義,這意味着将變量emma的值傳給person,這個值可能是任意一種資料類型,甚至是一個複雜的表達式。
宏可以有多個參數,使用時參數的次序是無關的,但是隻能使用宏中定義的參數,并且對所有參數指派。如:
<#macro greet person color>
<font size="+2" color="${color}"> Hello ${person}!</font>
<@greet color="black" person="emma" />正确
<@greet person="emma" />錯誤,color沒有指派,此時,如果在定義宏時為color定義預設值<#macro greet person color="black">這樣的話,這個使用方法就是正确的。
<@greet color="black" person="emma" bgcolor="yellow" />錯誤,宏greet定義中未指定bgcolor這個參數
. 編寫函數
2.注冊與使用
有兩種方式:
(1).在模闆檔案中注冊,在模闆中使用
<#assign getSysdate= package com.freemarker.test.SqlGetSysdateMethod?new()>
<#assign curdate= getSysdate(yyyy-MM-ddt)/>
(2).處理模闆檔案時注冊關鍵代碼:
Map<String,Object> root=new HashMap<String, Object>();
root.put(getSysdate, new StringLengthMethod());
Configuration config=new Configuration();
File file=new File(templatePath);
//并加載模闆檔案
config.setDirectoryForTemplateLoading(file);
//設定包裝器,并将對象包裝為資料模型
config.setObjectWrapper(new DefaultObjectWrapper());
//擷取模闆,并設定編碼方式,這個編碼必須要與頁面中的編碼格式一緻
Template template=config.getTemplate(templateName,templateEncoding);
//合并資料模型與模闆
template.process(root, out);
<#macro pagination totalCount pageSize>
<#--聲明一個函數transform 轉換uri,在新的uri上pager_offset參數 -->
<#assign transform = "util.TransformURI"?new()>
<#--聲明一個函數,得到目前頁碼-->
<#assign pagerOffset = "util.PagerOffset"?new()>
<#--聲明一個函數,根據傳入的totalCount,pageSize得到總頁數-->
<#assign pagerCount = "util.PageCount"?new()>
<#assign pageCount=pagerCount(totalCount,pageSize)>
<#--得到目前的URI和請求參數,得到目前的頁碼-->
<#if request.queryString?exists>
<#assign uri=request.requestURI+"?"+request.queryString>
<#assign pageIndex=pagerOffset(uri)>
<#assign new_uri=transform(uri)>
<#else>
<#assign uri=request.requestURI>
</#if>
<#if (pageIndex>pageCount)>
<#assign pageIndex=pageCount>
<#if (pageIndex>1)>
<a href="${new_uri+1}" title="首頁">&lt;&lt;</a>
<#--如果前面頁數過多,顯示"..."-->
<#if (pageIndex>5)>
<#assign prevPages=pageIndex-9>
<#if prevPages lt 1>
<#assign prevPages=1>
</#if>
<#assign start=pageIndex-4>
<a href="${new_uri+prevPages}" title="向前5頁">...</a>
<#assign start=1>
</#if>
<#-- 顯示目前頁附近的頁-->
<#assign end=pageIndex+4>
<#if (end>pageCount)>
<#assign end=pageCount>
<#list start..end as index>
<#if pageIndex==index>
<b>${index}</b>
<#else>
<a href="${new_uri+index}">${index}</a>
</#list>
<#--如果後面頁數過多,顯示"...":-->
<#if (end lt pageCount)>
<#assign endend=end+5>
<#if (end>pageCount)>
<#assign end=pageCount>
<a href="${new_uri+end}" title="向後5頁">...</a>
<#-- 顯示"下一頁":-->
<#if (pageIndex lt pageCount)>
<a href="${new_uri+pageCount}" title="末頁">&gt;&gt;</a>
</#macro>
自定義了三個方法:
PageCount.java
package util;
import java.util.List;
import freemarker.template.TemplateMethodModel;
import freemarker.template.TemplateModelException;
/**
* 根據傳入的參數,計算出所有的頁數
* @author legolas
*/
public class PageCount implements TemplateMethodModel {
@Override
public Object exec(List args) throws TemplateModelException {
Integer totalCount = 0;
Integer pageSize = 0;
try {
totalCount = Integer.parseInt((String) args.get(0));
pageSize = Integer.parseInt((String) args.get(1));
} catch (NumberFormatException e) {
throw new TemplateModelException("請輸入正确的總記錄數和頁面記錄數");
}
Integer pageCount = totalCount / pageSize
+ (totalCount % pageSize == 0 ? 0 : 1);
return pageCount;
}
}
TransformURI.java
package util;
* 根據傳入的uri,在uri後面加上分頁參數
*
public class TransformURI implements TemplateMethodModel{
String uri = (String) args.get(0);
int n = uri.lastIndexOf("?");
if (n == -1) {
return uri + "?pager_offset=";
if (uri.lastIndexOf("?pager_offset") != -1) {
uri = uri.substring(0, uri.lastIndexOf("=") + 1);
return uri;
String queryString = uri.substring(n + 1, uri.length());
String suburi = uri.substring(0, n + 1);
String[] strings = queryString.split("&");
for (int i = 0; i < strings.length; i++) {
if (strings[i].startsWith("pager_offset")) {
continue;
}
suburi += strings[i];
suburi += "&pager_offset=";
}
return suburi;
}
}
PagerOffset.java
* 得到目前的頁碼
public class PagerOffset implements TemplateMethodModel {
public Object exec(List args) throws TemplateModelException {
String[] string = uri.split("pager_offset=");
if (string.length == 1) {
return 1;
} else {
Integer pager_offset = 1;
try {
pager_offset = Integer.parseInt(string[1]);
} catch (NumberFormatException e) {
pager_offset = 1;
return pager_offset;
* FreeMarker作為視圖元件是由Servlet負責加載該模闆,并使用資料模型填充該模闆,并且将填充後
的标準HTML響應輸出給浏覽者.
* 在Struts2架構的支援下,Struts2架構充當了之前的Servlet角色.
* 為了使所有的使用者請求都經過Struts2架構處理,我們将所有的FreeMarker模闆放在WEB-INF/ftl路徑下.
* 放在WEB-INF/路徑下可以提供更好的安全性,因為Web容器會保證浏覽者無法通路到WEB-INF/路徑下的資源.
1>.FreeMarker模闆内建的變量
2>.ValueStack中的變量.
3>.ActionContext中的變量.
4>.HttpServletRequest範圍的屬性.
5>.HttpSession範圍的屬性.
6>.ServletContext範圍的屬性.
stack:代表ValueStack本身,可這樣通路其中變量:${stack.findString('ognl expr')}
action:代表剛剛執行過的Action執行個體.
response:代表HttpServletResponse執行個體.
request:代表HttpServletRequest執行個體.
res:代表HttpServletRequest執行個體.
session:代表HttpSession執行個體.
application:代表ServletContext執行個體.
base:代表使用者請求的上下文路徑.
<#if Application.attributeName?exists>
${Application.attributeName}
使用struts2标簽輸出:<@s.property value="%{Application.attributeName}"/>
<#if Parameter.parameter?exists>
${Parameter.parameter}