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>,输出到前台页面就会自动转码为:<script>alert("abc");</script>,这样就不会出现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字符都需要用实体引用来代替(比如<代替< )
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)内建函数 日期,时间,时间日期类型
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 >
浙公网安备 33010602011771号