3.2 输出变量值 <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

FreeMarker 的表达式输出变量时 , 这些变量可以是顶层变量 , 也可以是 Map 对象中的变量 , 还可以是集合中的变量 , 并可以使用点 (.) 语法来访问 Java 对象的属性 . 下面分别讨论这些情况

1, 顶层变量
所谓顶层变量就是直接放在数据模型中的值 , 例如有如下数据模型 :
Map root = new HashMap();   //
创建数据模型
root.put("name","annlee");   //name
是一个顶层变量

对于顶层变量 , 直接使用 ${variableName} 来输出变量值 , 变量名只能是字母 , 数字 , 下划线 ,$,@ # 的组合 , 且不能以数字开头号 . 为了输出上面的 name 的值 , 可以使用如下语法 :
${name}

2, 输出集合元素
如果需要输出集合元素 , 则可以根据集合元素的索引来输出集合元素 , 集合元素的索引以方括号指定 . 假设有索引 :
["
星期一 "," 星期二 "," 星期三 "," 星期四 "," 星期五 "," 星期六 "," 星期天 "]. 该索引名为 week, 如果需要输出星期三 , 则可以使用如下语法 :
${week[2]}   //
输出第三个集合元素

此外 ,FreeMarker 还支持返回集合的子集合 , 如果需要返回集合的子集合 , 则可以使用如下语法 :
week[3..5]   //
返回 week 集合的子集合 , 子集合中的元素是 week 集合中的第 4-6 个元素

3, 输出 Map 元素
这里的 Map 对象可以是直接 HashMap 的实例 , 甚至包括 JavaBean 实例 , 对于 JavaBean 实例而言 , 我们一样可以把其当成属性为 key, 属性值为 value Map 实例 . 为了输出 Map 元素的值 , 可以使用点语法或方括号语法 . 假如有下面的数据模型 :
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);

为了访问数据模型中名为 struts2 的书的作者的名字 , 可以使用如下语法 :
book.author.name    //
全部使用点语法
book["author"].name
book.author["name"]    //
混合使用点语法和方括号语法
book["author"]["name"]   //
全部使用方括号语法

使用点语法时 , 变量名字有顶层变量一样的限制 , 但方括号语法没有该限制 , 因为名字可以是任意表达式的结果 .

3.3, 字符串操作

FreeMarker 的表达式对字符串操作非常灵活 , 可以将字符串常量和变量连接起来 , 也可以返回字符串的子串等 .

字符串连接有两种语法 :
1,
使用 ${..} #{..} 在字符串常量部分插入表达式的值 , 从而完成字符串连接 .
2,
直接使用连接运算符 + 来连接字符串

例如有如下数据模型 :
Map root = new HashMap(); root.put("user","annlee");
下面将 user 变量和常量连接起来 :
${"hello, ${user}!"}   //
使用第一种语法来连接
${"hello, " + user + "!"} //
使用 + 号来连接
上面的输出字符串都是 hello,annlee!, 可以看出这两种语法的效果完全一样 .

值得注意的是 ,${..} 只能用于文本部分 , 不能用于表达式 , 下面的代码是错误的 :
<#if ${isBig}>Wow!</#if>
<#if "${isBig}">Wow!</#if>
应该写成 :<#if isBig>Wow!</#if>

截取子串可以根据字符串的索引来进行 , 截取子串时如果只指定了一个索引值 , 则用于取得字符串中指定索引所对应的字符 ; 如果指定两个索引值 , 则返回两个索引中间的字符串子串 . 假如有如下数据模型 :
Map root = new HashMap(); root.put("book","struts2,freemarker");
可以通过如下语法来截取子串 :
${book[0]}${book[4]}   //
结果是 su
${book[1..4]}     //
结果是 tru

3.4 集合连接运算符

这里所说的集合运算符是将两个集合连接成一个新的集合 , 连接集合的运算符是 +, 看如下的例子 :
<#list ["
星期一 "," 星期二 "," 星期三 "] + [" 星期四 "," 星期五 "," 星期六 "," 星期天 "] as x>
${x}
</#list>
输出结果是 : 星期一 星期二 星期三 星期四 星期五 星期六 星期天

3.5 Map 连接运算符

Map 对象的连接运算符也是将两个 Map 对象连接成一个新的 Map 对象 ,Map 对象的连接运算符是 +, 如果两个 Map 对象具有相同的 key, 则右边的值替代左边的值 . 看如下的例子 :
<#assign scores = {"
语文 ":86," 数学 ":78} + {" 数学 ":87,"Java":93}>
语文成绩是 ${scores. 语文 }
数学成绩是 ${scores. 数学 }
Java
成绩是 ${scores.Java}
输出结果是 :
语文成绩是 86
数学成绩是 87
Java
成绩是 93

3.6 算术运算符

FreeMarker 表达式中完全支持算术运算 ,FreeMarker 支持的算术运算符包括 :+, - , * , / , % 看如下的代码 :
<#assign x=5>
${ x * x - 100 }
${ x /2 }
${ 12 %10 }
输出结果是 :
-75   2.5   2

在表达式中使用算术运算符时要注意以下几点 :
1,
运算符两边的运算数字必须是数字
2,
使用 + 运算符时 , 如果一边是数字 , 一边是字符串 , 就会自动将数字转换为字符串再连接 , :${3 + "5"}, 结果是 :35

使用内建的 int 函数可对数值取整 , :
<#assign x=5>
${ (x/2)?int }
${ 1.1?int }
${ 1.999?int }
${ -1.1?int }
${ -1.999?int }
结果是 :2 1 1 -1 -1

3.7 比较运算符

表达式中支持的比较运算符有如下几个 :
1,=
或者 ==: 判断两个值是否相等 .
2,!=:
判断两个值是否不等 .
3,>
或者 gt: 判断左边值是否大于右边值
4,>=
或者 gte: 判断左边值是否大于等于右边值
5,<
或者 lt: 判断左边值是否小于右边值
6,<=
或者 lte: 判断左边值是否小于等于右边值

注意 := != 可以用于字符串 , 数值和日期来比较是否相等 , = != 两边必须是相同类型的值 , 否则会产生错误 , 而且 FreeMarker 是精确比较 ,"x","x ","X" 是不等的 . 其它的运行符可以作用于数字和日期 , 但不能作用于字符串 , 大部分的时候 , 使用 gt 等字母运算符代替 > 会有更好的效果 , 因为 FreeMarker 会把 > 解释成 FTL 标签的结束字符 , 当然 , 也可以使用括号来避免这种情况 , :<#if (x>y)>

3.8 逻辑运算符

逻辑运算符有如下几个 :
逻辑与 :&&
逻辑或 :||
逻辑非 :!
逻辑运算符只能作用于布尔值 , 否则将产生错误

3.9 内建函数

FreeMarker 还提供了一些内建函数来转换输出 , 可以在任何变量后紧跟 ?,? 后紧跟内建函数 , 就可以通过内建函数来轮换输出变量 . 下面是常用的内建的字符串函数 :
html:
对字符串进行 HTML 编码
cap_first:
使字符串第一个字母大写
lower_case:
将字符串转换成小写
upper_case:
将字符串转换成大写
trim:
去掉字符串前后的空白字符

下面是集合的常用内建函数
size:
获取序列中元素的个数

下面是数字值的常用内建函数
int:
取得数字的整数部分 , 结果带符号

例如 :
<#assign test="Tom & Jerry">
${test?html}
${test?upper_case?html}
结果是 :Tom &amp; Jerry   TOM &amp; JERRY

3.10 空值处理运算符

FreeMarker 对空值的处理非常严格 ,FreeMarker 的变量必须有值 , 没有被赋值的变量就会抛出异常 , 因为 FreeMarker 未赋值的变量强制出错可以杜绝很多潜在的错误 , 如缺失潜在的变量命名 , 或者其他变量错误 . 这里所说的空值 , 实际上也包括那些并不存在的变量 , 对于一个 Java null 值而言 , 我们认为这个变量是存在的 , 只是它的值为 null, 但对于 FreeMarker 模板而言 , 它无法理解 null ,null 值和不存在的变量完全相同 .

为了处理缺失变量 ,FreeMarker 提供了两个运算符 :
!:
指定缺失变量的默认值
??:
判断某个变量是否存在

其中 ,! 运算符的用法有如下两种 :
variable!
variable!defaultValue, 第一种用法不给缺失的变量指定默认值 , 表明默认值是空字符串 , 长度为 0 的集合 , 或者长度为 0 Map 对象 .

使用 ! 指定默认值时 , 并不要求默认值的类型和变量类型相同 . 使用 ?? 运算符非常简单 , 它总是返回一个布尔值 , 用法为 :variable??, 如果该变量存在 , 返回 true, 否则返回 false

3.11 运算符的优先级

FreeMarker 中的运算符优先级如下 ( 由高到低排列 ):
1,
一元运算符 :!
2,
内建函数 :?
3,
乘除法 :*, / , %
4,
加减法 :- , +
5,
比较 :> , < , >= , <= (lt , lte , gt , gte)
6,
相等 :== , = , !=
7,
逻辑与 :&&
8,
逻辑或 :||
9,
数字范围 :..
海浪连续两篇FreeMarker基本语法详解及模板文件的组成就分享到这里了,希望大家能够有收获。