一、介绍
什么是FreeMarker?
FreeMarker 是一款 模板引擎:即一种基于模板和要改变的数据,并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。
模板编写为FreeMarker Template Language (FTL)。它是简单的,专用的语言, 不是 像PHP那样成熟的编程语言。那就意味着要准备数据在真实编程语言中来显示,比如数据库查询和业务运算,之后模板显示已经准备好的数据。在模板中,你可以专注于如何展现数据,而在模板之外可以专注于要展示什么数据。
这种方式通常被称为 MVC (模型视图控制器) 模式,对于动态网页来说,是一种特别流行的模式。它帮助从开发人员中分离出网页设计师(HTML设计师)。设计师无需面对模板中的复杂逻辑,在没有程序员来修改或重新编译代码时,也可以修改页面的样式。
而FreeMarker最初的设计,是被用来在MVC模式的Web开发框架中生成HTML页面的,它没有被绑定到 Servlet或HTML或任意Web相关的东西上。它也可以用于非Web应用环境中。
以下内容来自:http://www.oschina.net/p/freemarker
FreeMarker具有一些编程的能力,但通常由Java程序准备要显示的数据,由FreeMarker生成页面,通过模板显示准备的数据,简单来讲就是模板加数据模型,然后输出页面(如下图)
FreeMarker不是一个Web应用框架,而适合作为Web应用框架一个组件
FreeMarker与容器无关,因为它并不知道HTTP或Servlet;
FreeMarker同样可以应用于非Web应用程序环境
FreeMarker更适合作为Model2框架(如Struts)的视图组件,你也可以在模板中使用JSP标记库
FreeMarker是免费的
而且还可以通过Eclipse的插件来编辑FreeMarker,经过验证,FreeMarker 最好的 Eclipse 编辑插件是 JBoss Tools。
FreeMarker特性
1、通用目标
能够生成各种文本:HTML、XML、RTF、Java源代码等等
易于嵌入到你的产品中:轻量级;不需要Servlet环境
插件式模板载入器:可以从任何源载入模板,如本地文件、数据库等等
你可以按你所需生成文本:保存到本地文件;作为Email发送;从Web应用程序发送它返回给Web浏览器
2、强大的模板语言
所有常用的指令:include、if/elseif/else、循环结构
在模板中创建和改变变量
几乎在任何地方都可以使用复杂表达式来指定值
命名的宏,可以具有位置参数和嵌套内容
名字空间有助于建立和维护可重用的宏库,或者将一个大工程分成模块,而不必担心名字冲突
输出转换块:在嵌套模板片段生成输出时,转换HTML转义、压缩、语法高亮等等;你可以定义自己的转换
3、通用数据模型
FreeMarker不是直接反射到Java对象,Java对象通过插件式对象封装,以变量方式在模板中显示
你可以使用抽象(接口)方式表示对象(JavaBean、XML文档、SQL查询结果集等等),告诉模板开发者使用方法,使其不受技术细节的打扰
4、为Web准备
在模板语言中内建处理典型Web相关任务(如HTML转义)的结构
能够集成到Model2 Web应用框架中作为JSP的替代
支持JSP标记库
为MVC模式设计:分离可视化设计和应用程序逻辑;分离页面设计员和程序员
5、智能的国际化和本地化
字符集智能化(内部使用UNICODE)
数字格式本地化敏感
日期和时间格式本地化敏感
非US字符集可以用作标识(如变量名)
多种不同语言的相同模板
6、强大的XML处理能力
<#recurse> 和<#visit>指令(2.3版本)用于递归遍历XML树
在模板中清楚和直觉的访问XML对象模型
在Maven中使用它:
<dependency>
<groupId>freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.9</version>
</dependency>
maven依赖 下载地址:http://freemarker.sourceforge.net/freemarkerdownload.html
二、使用环境搭建
创建一个Java项目,这里名为freemarker,在根目录下创建一个名为ftl的文件夹(PS:用来存放freemarker模板),引入freeemarker jar包。
创建一个FreeMarkerDemo类,用来生成模板以及处理模板与数据之间的关系并输出:
//第一步:实例化Freemarker的配置类 Configuration conf = new Configuration(); //第二步:给配置类设置路径 String dir = "D:\\java21\\freemarker\\ftl\\"; conf.setDirectoryForTemplateLoading(new File(dir)); Template template = conf.getTemplate("freemarker.html"); //第三步:处理模板及数据之间将数据与模板合成一个HTML //第四步:输出html Writer out = new FileWriter(new File(dir+"hello.html"));
定义一个Person对象:
public class Person {
private String id;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
出例子
定义数据
//定义数据
Map<String,Object> root = new HashMap<String,Object>();
Person p = new Person();
p.setId("111");
p.setName("哈哈哈");
root.put("person", p);
template.process(root, out);
out.flush();
out.close();
模板页面书写
${person.id}<br /> ${person.name}
点击hello.html查看结果
遍历List例子
定义数据
//遍历List List<String> persons = new ArrayList<String>(); persons.add("阿灵罗"); persons.add("罗零"); persons.add("灵罗"); root.put("persons",persons); template.process(root, out); out.flush(); out.close();
- 模板页面书写:
<#list persons as person> ${person} </#list>
<!--获取当前索引 -->
<#list persons as p> ${p_index} </#list>
遍历Map
定义数据:
//遍历Map
Map<String,String> mx = new HashMap<String,String>();
mx.put("alingluo", "阿灵罗");
mx.put("lling", "罗零");
root.put("mx", mx);
template.process(root, out);
out.flush();
out.close();
模板页面书写:
<!--Map写法 -->
${mx.alingluo}/${mx.lling} <#list mx?keys as k> ${mx[k]} </#list>
ListMap遍历
定义数据
//遍历List<Map>
List<Map<String,String>> maps = new ArrayList<Map<String,String>>();
Map<String,String> pms1 = new HashMap<String,String>();
pms1.put("id1", "张三");
pms1.put("id2", "李四");
Map<String,String> pms2 = new HashMap<String,String>();
pms2.put("id1", "张三");
pms2.put("id2", "李四");
maps.add(pms1);
maps.add(pms2);
root.put("maps", maps);
template.process(root, out);
out.flush();
out.close();
模板页面书写:
<#list maps as m> ${m.id1}/${m.id2} </#list> <#list maps as m> <#list
m?keys as k> ${m[k]} </#list> </#list>
在模板中赋值
root.put("world", "世界你好");
<!-- 在模板中赋值 -->
1:<#assign x=0 /> ${x}
2:<#assign x="${world}" /> ${x}
3:<#assign x>世界太好了</#assign> ${x}
4:<#assign x>
<#list ["星期一", "星期二", "星期三",
"星期四", "星期五", "星期六", "星期天"] as n> ${n}
</#list>
</#assign>
${x}
生成页面对应的值:
<!-- 判断 -->
<#list ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"] as n>
<#if n != "星期一">
${n}
</#if>
</#list>
<#list ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"] as n>
<#if n_index != 0>
${n}
</#if>
</#list>
<#list ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"] as n>
<#if (n_index == 1) || (n_index == 3)>
${n}
</#if>
</#list>
<!-- else -->
<#list ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"] as n>
<#if (n_index == 1) || (n_index == 3)>
${n} --红色
<#else>
${n} --绿色
</#if>
</#list>
生成页面效果
时间格式
模板页面效果如下:
<!--时间格式 -->
1:${cur_time?date}
2:${cur_time?datetime}
3:${cur_time?time}
生成页面效果如下:
FreeMarkerDemo全部代码:
public class FreeMarkerDemo {
public static void main(String[] args) throws IOException, TemplateException {
//第一步:实例化Freemarker的配置类
Configuration conf = new Configuration();
//第二步:给配置类设置路径
String dir = "E:\\java\\freemarker\\ftl\\";
conf.setDirectoryForTemplateLoading(new File(dir));
Template template = conf.getTemplate("freemarker.html");
//第三步:处理模板及数据之间将数据与模板合成一个HTML
//第四步:输出html
Writer out = new FileWriter(new File(dir+"hello.html"));
//定义数据
// Map root = new HashMap();
//执行生成
//定义数据
Map<String,Object> root = new HashMap<String,Object>();
Person p = new Person();
p.setId("111");
p.setName("哈哈哈");
root.put("person", p);
root.put("world", "世界你好");
//遍历List
List<String> persons = new ArrayList<String>();
persons.add("阿灵罗");
persons.add("罗零");
persons.add("灵罗");
root.put("persons",persons);
root.put("cur_time", new Date());
//遍历Map
Map<String,String> mx = new HashMap<String,String>();
mx.put("alingluo", "阿灵罗");
mx.put("lling", "罗零");
root.put("mx", mx);
//遍历List<Map>
List<Map<String,String>> maps = new ArrayList<Map<String,String>>();
Map<String,String> pms1 = new HashMap<String,String>();
pms1.put("id1", "张三");
pms1.put("id2", "李四");
Map<String,String> pms2 = new HashMap<String,String>();
pms2.put("id1", "张三");
pms2.put("id2", "李四");
maps.add(pms1);
maps.add(pms2);
root.put("maps", maps);
//定义数据
root.put("val", null);
template.process(root, out);
out.flush();
out.close();
}
}
freemarker.html全部代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
${person.id}
<br /> ${person.name} <#list persons as person> ${person} </#list>
<!--Map写法 -->
${mx.alingluo}/${mx.lling} <#list mx?keys as k> ${mx[k]} </#list>
<!--List<Map>写法 -->
<#list maps as m> ${m.id1}/${m.id2} </#list> <#list maps as m> <#list
m?keys as k> ${m[k]} </#list> </#list>
<!--获取当前索引 -->
<#list persons as p> ${p_index} </#list>
<!-- 在模板中赋值 -->
1:<#assign x=0 /> ${x}
2:<#assign x="${world}" /> ${x}
3:<#assign x>世界太好了</#assign> ${x}
4:<#assign x>
<#list ["星期一", "星期二", "星期三",
"星期四", "星期五", "星期六", "星期天"] as n> ${n}
</#list>
</#assign>
${x}
<!-- 判断 -->
<#list ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"] as n>
<#if n != "星期一">
${n}
</#if>
</#list>
<#list ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"] as n>
<#if n_index != 0>
${n}
</#if>
</#list>
<#list ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"] as n>
<#if (n_index == 1) || (n_index == 3)>
${n}
</#if>
</#list>
<!-- else -->
<#list ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"] as n>
<#if (n_index == 1) || (n_index == 3)>
${n} --红色
<#else>
${n} --绿色
</#if>
</#list>
<!--时间格式 -->
1:${cur_time?date}
2:${cur_time?datetime}
3:${cur_time?time}
<!-- null -->
${val!}
<!-- 宏定义 -->
1:
<#macro table u>
${u}
</#macro>
<@table u=8 />
2:
<#macro table u>
${u}
<#nested/>
</#macro>
<@table u=8 >这是8</@table>
</body>
</html>
生成的HTML页面内容如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
111
<br /> 哈哈哈 阿灵罗 罗零 灵罗
<!--Map写法 -->
阿灵罗/罗零 阿灵罗 罗零
<!--List<Map>写法 -->
张三/李四 张三/李四 李四 张三 李四 张三
<!--获取当前索引 -->
0 1 2
<!-- 在模板中赋值 -->
1: 0
2: 世界你好
3: 世界太好了
4: 世界真美好
星期一
星期二
星期三
星期四
星期五
星期六
星期天
<!-- 判断 -->
星期二
星期三
星期四
星期五
星期六
星期天
星期二
星期三
星期四
星期五
星期六
星期天
星期二
星期四
<!-- else -->
星期一 --绿色
星期二 --红色
星期三 --绿色
星期四 --红色
星期五 --绿色
星期六 --绿色
星期天 --绿色
<!--时间格式 -->
1:2017-5-8
2:2017-5-8 10:56:56
3:10:56:56
<!-- null -->
<!-- 宏定义 -->
1:
8
2:
8
这是8
</body>
</html>