http://blog.youkuaiyun.com/liaomin416100569/article/details/78349072
一.freemarker的一些特点和使用
freemarker和JSP都是模板,freemarker相对于jsp特别之处:freemarker中有宏(类似java中的方法)FreeMarker标记: 1) $ : ${expression} 输出,运算
2) # :标准的FTL标记
3) @作为用户定义指令使用宏变量时,使用@替代FTL标记中的#
4)注释<#---->
freemarker可用于javase和javaee创建项目导入jar包:可用maven导入,或手动添加jar包
在eclipse或myeclipse工具中加入插件,放置在eclipse或myeclipse安装目录的plugin目录中
在创建好的项目根路径下创建一个目录model(目录名自定义)
model目录下定义fmk.ftl(文件名自定义)文件,fmk.ftl中定义模板内容
<html>
<head>
<title>Welcome!</title>
</head>
<body>
<h1>Welcome ${user}!</h1></br>
<h1>who's name is ${t.name}!</h1></br>
</body>
</html>
创建java类:
public class TestFmk {
public static void main(String[] args) throws Exception {
Configuration cfg = new Configuration();
//配置ftl查找目录
cfg.setDirectoryForTemplateLoading(new File("model"));
//设置数据的抓取模式
cfg.setObjectWrapper(new DefaultObjectWrapper());
//构建数据
Map latest = new HashMap();
latest.put("name", "ssg");
Map root = new HashMap();
root.put("t", latest);
root.put("user", "man");
// 实例化模版对象
Template temp = cfg.getTemplate("fmk.ftl");
//定义文件输出流
FileOutputStream fileOutputStream=new FileOutputStream("c:/a.html");
//把模版内容输出到html文件中
Writer out = new OutputStreamWriter(fileOutputStream);
temp.process(root, out);
out.flush();
//将ftl文件的内容输出到控制台
/*Writer out = new OutputStreamWriter(System.out);
temp.process(root, out);
out.flush();*/
}
二.ftl文件中标签的使用:
1.if,elseif,else指令
类中: root.put("sex", 0);
ftl文件:
<#if sex=0>
性别:<h1>男</h1></br>
<#elseif sex=1>
性别:<h1>女</h1></br>
<#else>
性别:<h1>未知</h1></br>
</#if>
2.switch, case, default, break指令
<#switch sex>
<#case 0>
男
<#break>
<#case 1>
女
<#break>
<#default>
未知
</#switch>
3.list, break指令(类似foreach循环)
临时变量_index:是list当前值的下标
临时变量_has_next:判断list是否还有值
类中:
String[] strings=new String[]{"1","2","3"};
root.put("array", strings);
ftl文件:
<#--数组或集合名 as 变量名-->
<#list array as tmp>
<#--变量名_index 获取数组或集合的索引,索引从0开始-->
${tmp_index}<br>
${tmp}
<#if tmp_index=2>
<#break>
</#if>
</#list>
4.assign指令:ftl文件中定义变量或数组
assin定义变量:
<#--
<#assign home>sheng</#assign>
-->
<#assign home='深圳'>
${home}
assin定义数组:
<#assign arr=[1,2,3]>
<#list arr as t>
${t}
</#list>
5.include,import指令
新建a.ftl,b.ftl,c.ftl
a.ftl中定义<#assign age=12>
b.ftl中定义<#assign age=12>
1>include指令:
<#include filename>or<#include filename options>
options包含两个属性encoding=”GBK” 编码格式parse=true 是否作为ftl语法解析,默认是true
c.ftl包含a.ftl,b.ftl中的内容:
<#include "a.ftl" >
<#include "b.ftl" >
${age}
最终输出b.ftl中的变量,包含进来的内容后面的覆盖前面的内容
2>import指令
c.ftl import a.ftl,b.ftl中的内容:分别输出a.ftl,b.ftl中age的值
<#include "a.ftl" as a>
<#include "b.ftl" as b>
${a.age}
${b.age}
6.macro, nested, return指令:
1.macro
<#--定义宏: macro 宏名 参数(多个参数间空格隔开),
参数可以赋默认值,亦可以不赋默认值,参数的默认值还可以为另一个参数
参数可以传参,可以传数组/集合
-->
<#macro test foo bar="BAR" baaz=-1>
Test text, and the params: ${foo}, ${bar},${baaz}
</#macro>
<#--调用宏时,没有默认值的参数必须要赋值,有默认值的参数可以修改值-->
<@test foo="a" />
<@test foo="a" bar="b" baaz=5*5-2 />
<@test foo="a" bar="b" />
<@test foo="a" baaz=5*5-2 />
<#--定义宏时可以不带参数,直接在标签中写-->
<#macro ss>hello</#macro>
<#--调用-->
<@ss/>
2)nested
<#--nested中可以定义参数,多个参数间用,隔开-->
<#macro do_thrice>
<#nested 1>
<#nested 2>
<#nested 3>
</#macro>
<#--调用: @宏名 ; 参数(参数名随意写,参数的个数根据nested中定义的个数)-->
<@do_thrice ; y >
${y}Anything.
</@do_thrice>
<#macro repeat count>
<#list 1..count as x>
<#nested x, x/2, x==count>
</#list>
</#macro>
<@repeat count=4 ; a, b, c>
${a}. ${b}<#if c> Last!</#if>
</@repeat>
3)return
<#macro test>
Test text
<#return>
Will not be printed.
</#macro>
<@test/>
三.FreeMarker问题总结
1:特殊字符的显示
"的显示:${"\""} \的显示:${"\\"}
raw字符串,被认为是纯文本:
${r"${foo}"}
${r"C:\foo\bar"}
输出:
${foo}
C:\foo\bar
2:使用过程当中容易出错的地方
if标签错误的用法:
<#if ${isBig}>Wow!</#if>
<#if "${isBig}">Wow!</#if>
if正确的用法:
<#if isBig>Wow!</#if>
FreeMarker对null值有严格的校验,它将其视为missing
variable,报错!。为了防止错误发生我们可以为其设置当表
达式为null时的默认值:stockNum?default('')
&&(and)、||(or)、!(not),只能用于布尔值
FreeMarker是区分大小写的
3:FTL内置的处理函数
用法类似访问对象的子变量,只是使用"?"替代".",
例如:${user?upper_case}
1)字符串
html-对字符串进行HTML编码
cap_first-使字符串第一个字母大写
lower_case-将字符串转换成小写
upper_case-将字符串转换成大写
trim-去掉字符串前后的空白字符
length –取得字符串长度
js_string---包含的特殊字符(如回车、\”),转化成变量可以接收的值
例:
<#assign beanName = 'The "foo" bean.'>
var BEAN_NAME = "${beanName?j_string}";
结果:String BEAN_NAME = "The \"foo\" bean.";
2)对于数字
int-取得数字的整数部分(如-1.9?int的结果是-1 )
float
round
3)sequence序列
(对应java里的list、数组等非键值对的集合)与hash键值对的集合
size-获得序列中元素的数目
keys---返回hash里的所有keys, 返回结果类型sequence
values---返回hash里的所有value, 返回结果类型sequence
//构建数据
Map latest = new HashMap();
latest.put("name", "ssg");
latest.put("age", 11);
Map root = new HashMap();
root.put("t", latest);
${t?size}
<#list t?keys as key>
${key}
</#list>
<#list t?values as v>
${v}
</#list>
Xx代表集合,判定集合是否为空
<#if (xx.empty)>
</#if>
4)其他处理
<#if list ?exists>和${listone?if_exists} 及其简化写法
<#if list ?exists> 用作逻辑判断,返回的是true或者false
${listone?if_exists} 用于输出的时候 如果存在输出,不存在就输出孔字符串
list ?exists 简化成 list??
listone?if_exists 简化成 listone!
listone.name?default("dn") 简化成 listone!dn
string---string(‘#’)、 string(‘是’,’否’)、 string(‘#.00’)、 string(‘yyyy-MM-dd hh:mm:ss’)、 string(‘#.##’)、 string(‘0.##’)、
string.currency:指定数值以¥42.00 显示