详细学习了一下freemarker,发现功能确实挺强大的,做个笔记……
FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯Java编写,被设计用来生成HTML Web页面,特别是基于MVC模式的应用程序,通常由Java程序准备要显示的数据,由FreeMarker生成页面,通过模板显示准备的数据,使用时需要freemarker.jar
一个简单的示例:
建立一个普通的java项目,引入freemarker.jar包,在项目目录下建立模板目录:templates在templates目录下,建立1.ftl模板文件,内容如下:hello,${username}!
public class FreemarkerUtil {
public Template getTemplate(String name) {
try {
// 通过Freemaker的Configuration读取相应的ftl
Configuration cfg = new Configuration();
// 设定去哪里读取相应的ftl模板文件
cfg.setDirectoryForTemplateLoading(new File("templates"));
// 在模板文件目录中找到名称为name的文件
Template temp = cfg.getTemplate(name);
return temp;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public void print(String name, Map<String, Object> root) {
try {
// 通过Template可以将模板文件输出到相应的流
Template temp = this.getTemplate(name);
temp.process(root, new PrintWriter(System.out)); // 输出到控制台
} catch (TemplateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void fprint(String name, Map<String, Object> root, String outFile) {
Writer out=null;
try {
// 通过一个文件输出流,就可以写到相应的文件中
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(
"E:\\eclipse\\freemarker\\WebContent\\" + outFile)),"UTF-8"));// 输出到文件中,比如html中
Template temp = this.getTemplate(name);
temp.setEncoding("utf-8");
temp.process(root, out);
out.flush();
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
} finally {
try {
if (out != null)
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}调用:
@Test
public void test01() {
//1、创建数据模型 数据模型是哈希表
Map<String,Object> root = new HashMap<String,Object>();
//2、为数据模型添加值
root.put("username", "张三");
//3、将数据模型和模板组合的数据输出到控制台
fu.print("01.ftl", root);
fu.fprint("01.ftl", root, "01.html");
}
这样将生成01.html且有01.ftl的内容hello,张三! 上面看出取值方式和el相似,通过反射获取bean的值,可以用 “.”,也可以用”[]”
现有一个User类:id,name,age,user为其一对象1 常用指令:if—else--,
<#if user.age lt 12>
${user.name}还是一个小孩
<#elseif user.age lt 18>
${user.name}快成年
<#else>
${user.name}已经成年
</#if>
list遍历集合
<#list users as user>
${user.id}----${user.name}--${user.age}<br/>
</#list>
include指令
<#include "/inc/top.ftl"/> 直接生成在同一个文件流中
2 空值处理
${user.id}-------${user.name}------${user.group!}------------
${user.group.name!} <#-- 这种方式加! freemarker仅仅只会判断group.name是不是空值 -->最好用${(user.group.name)!}
<#-- ${sss} 没有定义这个变量,会报异常! -->
${sss!} <#--没有定义这个变量,默认值是空字符串! -->
${sss!"abc"} <#--没有定义这个变量,默认值是字符串abc! -->
??运算符返回布尔值,如:variable??,如果变量存在,返回true,否则返回false。
3 数据输出:
<#assign username="那儿"/> <#--定义变量${username}-->
<#assign num=10> <#--定义一个数字${num+11} -->
<#assign str="10"/> ${str+11}
<#assign b=true/>
<#--${b}--> <#--不能直接输出数字或字符串以外的类型,使用xxx?string可以完成字符串转换,才能输出 -->
${b?string} <#-- ${b?string}("1","0") -->
${(a.d)???string} <#--??运算符返回布尔值 输出false-->
${now?string("yyyy-MM-dd HH:mm:ss")} <#--now 保存的是Date对象-->
${"hello"+username}<#--${"hello${username}"} 等价-->
<#--string 转换为data、datatime、time-->
<#assign bir="1979-12-02 12:22:33"?date("yyyy-MM-dd")>
<#assign bir="1979-12-02 12:22:33"?datetime("yyyy-MM-dd HH:mm:ss")> ${bir}
${"<br/>"?html}
[${"abcde"?left_pad(10,"--")}]
${1.8?int} freemarker 好多内建函数,可以满足各种输出,字符串处理等
4 序列和哈希表
<#assign nums=[1,3,4,56,33,43]/>
${nums?first}
<#assign nums=12..200/><#--定义了一个连续的序列12到199-->
<#--把上面的序列拆分-->
<#assign nums1=nums[1..10]>
<#list nums1 as num>
${num}
</#list>
${"你好,你还在等她吗,不要这样了"[0..8]}...<#--可以完成好多css完成的功能-->
<#assign maps={"1":"张三","2":"李四"}>
${maps["1"]}
<#--以下的代码可以将map的key转换为相应的序列-->
<#assign keys=maps?keys>
<#list keys as key>
${key}---${maps[key]}
<#assign users={"username":"张三","password":"123"}>
${users.username}---${users["password"]}
5 自定义指令
<#--hello自定义指令,hello后的都是参数(num,ok)-->
<#macro hello num ok>
<#list 1..num as n>
<h1>Hello${ok}${n}</h1>
</#list>
</#macro>
<#--使用指令时参数名不能省略-->
<@hello num=3 ok="World"/>
<#--参数指定初始值,指定初始值的参数要放在未被指定的后面,如省略则使用默认值-->
<#macro repeat num=10 ok="World">
<#list 1..num as n>
<h1>Hello${ok}${n}</h1>
</#list>
</#macro>
<@repeat/> <#--调用-->
<#macro test>
<#--nested会输出指令中的内容-->
<#nested 12 33/>
<#nested 11 22/>
<#nested 22 33/>
</#macro>
<@test;x,y>
<h1>你好-${x}--${y}</h1> <#--输出三次,参数不同<h1>你好-11--22</h1>-->
</@test>
6 变量
数据模型中的变量、模板中的变量、局部变量、循环变量
<#assign username="张三"> <#--模板中的变量名称和模型中的变量名称一致不是覆盖,而是隐藏-->
<#--使用.globals可以访问模型中的变量 ${.globals.username}-->
<#macro test>
<#--调用该指令后,会覆盖模板中的变量username,所以这种方式存在风险-->
<#--<#assign username="五一"/>-->
<#--使用local可以声明局部变量,所以在marco中一般用局部变量-->
<#local username="五一"/>
${username}
</#macro>
<@test/>
7 命名空间
<#--
使用include可能会出现覆盖,可以使用import来完成导入,并且加入名称空间
<#include "/inc/inc1.ftl"/>
<#include "/inc/inc2.ftl"/> -->
<#import "/inc/inc2.ftl" as inc2/>
<#import "/inc/inc1.ftl" as inc1/>
${inc2.username}
${inc1.username}
<#--将一个变量定义到名称空间中-->
<#assign age=12 in inc2/>
${inc2.age}
<#--访问名称空间中的自定义指令-->
<@inc1.test/>
12万+

被折叠的 条评论
为什么被折叠?



