freemarker 应用小结与注意事项

大家好,以下是我在应用freemarker框架中总结的一些问题和注意事项:

一、freemarker应用小结:

1 输出数字的几种形式:

整形数:
${num}这种输出方式是以字符串输出,而且,会每隔三位添加一个 ",",类似1,123的显示形式,使用${num?c}可以消除

以数字形式输出:${num?number}
货币形式输出:${num?string.currency}
以百分比模式输出:${num?string.percent}

浮点数:
输出和数字差不多,不过浮点数要个精确度的问题。一是可以通过配置文件的配置来设置,比如设置成0.##意思是保留两位有效数字。也可以在页面中 使用<#setting number_format="0.##"> 标记,效果是一样的。不过一个是整个应用程序的,一个是页面的。

2 xss 注入问题(基于同事改版后的freemarker插件):

对于${}输出变量,无需考虑XSS注入问题,freemarker会自动对${}进行编码。比如对于变量:<script>alert("abc");</script>,输出到前台页面就会自动转码为:&lt;script&gt;alert(&quot;abc&quot;);&lt;/script&gt;,这样就不会出现XSS注入漏洞。

对于含html标签的变量,如果想在页面中显示html效果,就需要使用no_encode方法,用法为${value?no_encode}。如果变量value是含html代码的字符串,如<a href=”http://www.163.com”>首页</a>,直接使用${}就会在页面中显示html代码而不是一个链接,使用no_encode方法就可以在页面中显示一个链接。、

3 多条件判断写法:

<#if condition>
   ...
 <#elseif condition2>
   ...
<#else>  
</#if>

不可写成:

<#if condition>...
<#else><#if condition>...</#if>
<#else>...
</#if>

或写为:

<#switch value>
<#case refValue1>
...
<#break>
<#default>
...
</#switch>

4 模板中的变量类型:

plain变量:可以在模板的任何地方访问,包括使用include指令插入的模板,使用assign指令创建和替换。
局部变量:在宏定义体中有效,使用local指令创建和替换。
循环变量:只能存在于指令的嵌套内容,由指令(如list)自动创建;它是在自定义指令的开始标记(<@...>的参数后面通过分号确定的,若有多个,要注意变量的顺序,如果在分号后面指定了比nested指令还多的变量,那么最后的循环变量将不会被创建(在嵌套内容中不会被定义。 )

eg:

<#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!

5 内建函数:

字符串使用的内建函数:

html: 字符串中所的特殊HTML字符都需要用实体引用来代替(比如<代替&lt; )
cap_first:字符串的第一个字母变为大写形式
lower_case:字符串的小写形式
upper_case:字符串的大写形式
trim:去掉字符串首尾的空格

数字使用的内建函数:
int:数字的整数部分(比如-1.9?int就是-1)

序列使用的内建函数:
size:序列中元素的个数

6 处理序列的内建函数:

1)first 第一个子变量

2)last 最后一个子变量

3)seq_contanis 序列包含…

eg:

<#assign x = ["red", 16, "blue", "cyan"]>
"blue": ${x?seq_contains("blue")?string("yes", "no")}

输出:"blue": yes

4)seq_index_of 第一次出现…时的位置 (返回序列中第一次出现该值时的索引位置)

如果序列不包含指定的值时返回-1,另外第二个参数表示搜索开始的地方,如果在同一个序列中相同的项可以多次出现时,这是很有用的。

<#assign names = ["Joe", "Fred", "Joe", "Susan"]>
No 2nd param: ${names?seq_index_of("Joe")}
-2: ${names?seq_index_of("Joe", -2)}

输出:-2: 0

5)seq_last_index_of 最后一次出现..的位置

如果序列不包含指定的值时返回-1,第二个参数来确定从哪里开始搜索的索引位置。

<#assign names = ["Joe", "Fred", "Joe", "Susan"]>
No 2nd param: ${names?seq_last_index_of("Joe")}
-2: ${names?seq_last_index_of("Joe", -2)}
输出:

No 2nd param: 2
-2: -1

6)reverse 反转序列

7)sort 排序

以升序方式存储序列并返回。这仅在子变量都是字符串时有效,或者子变量都是数字。

8)sort_by 以…来排序

用法案例:

<#list ls?sort_by("name") as i>

如果排序的子变量的层次比较深(也就是说,如果它是子变量中的子变量),那么你可以使用序列作为参数,它指定了子变量的名称,来向下引导所需的子变量

<#list members?sort_by(['name', 'last']) as m>

9)chunk 区块

这个内建函数分割序列到多个大小为函数的第一个参数给定的序列(就像mySeq?chunk(3))。结果是包含这些序列的一个序列。最后一个序列可能比给定的大小要小,处分第二个参数也给定了(比如mySeq?chunk(3, '-')),那个就是用来填充最后一个序列,以达到给定的大小。

eg:

<#assign seq = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']

<#list seq?chunk(4, '-') as row>
<#list row as cell>${cell} </#list>
</#list>

输出:

a b c d
e f g h
i j - -

10)内建函数 日期,时间,时间日期类型

date:仅仅年,月和日的部分被使用。
ime: 仅仅时,分,秒和毫秒的部分被使用。
datetime:日期和时间量部分都使用了
 
FreeMarker支持date、time、datetime三种类型,这三种类型的值无法直接指定,通常需要借助字符串的date、time、datetime三个内建函数进行转换才可以
<#assign test1 = "2009-01-22"?date("yyyy-MM-dd") />;
<#assign test2 ="16:34:43"?time("HH:mm:ss") />
<#assign test2 = "2009-01-22 17:23:45"?datetime("yyyy-MM-dd HH:mm:ss") />
 
${test2?string("yyyy-MM-dd HH:mm:ss")}
 
freemarker date数据时间 显示时需要注意
${datestring?string("MM-dd hh:mm")} hh:mm 为12小时制
${datestring?string("MM-dd HH:mm")} HH:mm 为24小时制
 
二、注意事项:

1 变量名只能是字母、数字、下划线、$、#、@ 的组合,且不能以数字开头。

2 ${}只能用于文本区段和字符串文字中使用,而不能出现于标记内,例如:<#if ${isBig}>Wow!</#if>写法是错误的,正确的应写为:<#if isBig>Wow!</#if>,且isBig是一个布尔值。

3 区别?size 与 ?string:

  ?size 来获得序列中元素的个数;

  ?string 取得字符串的长度;

另外:可用 expr!?size > 0 或 expr!?length > 0 来代替e  xpr?has_content

4 转义字符的应用:

< lt
<= lte
> gt
>= gte

<#if (a<b)> 或 <#if a lt b)>这两种写法是正确的。不可写成:<#if a<b >

 

 

 

 

posted on 2012-09-06 12:01  lifenping  阅读(1668)  评论(0)    收藏  举报

导航