关于FreeMarker的认知与使用,官方文档真的写的很好,这里只记录一些我作为初学者掌握的基本知识点,算是学习的索引吧。FreeMarker中文在线手册
什么是FreeMarker
FreeMarker是一个模板引擎,是一种基于模板和要改变的数据,并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。它不是面向最终用户的,而是一个java类库,是一款程序员可以嵌入他们所开发产品的组件。其核心是:模板 + 数据模型 = 输出。
FreeMarker的特点
- 彻底的分离表现层和业务逻辑
- 性能好,提高了开发效率(相比较jsp,不需要转换成servlet,再编译、执行)
- 使得开发过程中的人员分工更加明确(与第一点呼应)
- 学习成本低(掌握了jsp的语法,FreeMarker的使用和jsp很像,只关注不同的地方即可)
- 支持表达式、宏定义(类似jsp标签)(可以完美适配jsp)
FreeMarker与Jsp
FreeMarker与jsp在视觉上相似度很高,掌握jsp的基本语法,很快就能掌握FreeMarker的语法,但是FreeMarker与jsp有几点显著的不同,特此说明一下。首先FreeMarker不绑定Servlet,网络/Web环境,所以它不需要像jsp那样转换成servlet,再编译执行,可以极大的提高效率。另外,相比于jsp,它拥有更简洁的语法。再有,它的职责更加单一,只专注于展示。然而因为FreeMarker 不是一种标准,很少的工具和IDE来集成它。(然而,使用合适的设置, 大部分JSP标签库可以在 FreeMarker 模板中运行,除非它们基于 .tag 文件。)
FreeMarker在线测试网址
Online Freemarker Template Tester
FreeMarker数据模型
和java、jsp等都是差不多的
- 标量(字符串、数字、布尔值、日期/时间)
- 容器(哈希表、序列、集合)
- 子程序(方法和函数、用户自定义指令)
- 其他(结点)
FreeMarker算术运算
数字运算:+、-|、*、/、%
字符串运算:特别说下字符串拼接
${"hello,${name}"}
${"hello," + name}
FreeMarker逻辑、比较运算符
- 逻辑运算符(&&、||、!)
- 比较运算符(推荐使用:gt、lt、gte、lte、==、!=)
- 注意事项:
1.只能比较数字和日期,不能比较字符串,返回为布尔类型不能直接输出
2.由于FreeMarker会将>解释称FTL标记的结束符,所以对于>和>=可以使用括号来避免,如<#if (x>y)>
FreeMarker空值判断
FreeMarker是不识别空值的,这里的空值包括属性存在但为null和属性不存在两种情况,所以空值的判断尤为重要。
??:判断是否为空
- <#if object.attribute??></#if>:判断对象的属性是否不为null
- <#if (object.attribute)??></#if>:判断对象及对象的属性是否不为null
!:指定缺失变量的默认值,如果不指定则默认值是空字符串、长度为0的序列或者长度为0的map对象
- ${a!}:a未定义,不报错,默认没有任何输出
- ${a!’-’}:a未定义,不报错,得到“-”,不会为a赋值
- ${(user.name)!“默认值”}:若user或user.name为null,输出默认值
- ${user.name!“默认值”}:若user为null,报错,user.name为null,输出默认值
FreeMarker模板中的代码片段
- ${…}:称为插值(interpolation)
- 注释:格式:<#-- 内容 -->,不会出现在输出中
- FTL标签:它是FreeMarker的指令,不会输出打印,以#开头,自定义FTL标签以@代替#
FreeMarker基本指令
下面给出几个常见指令的使用
条件判断指令:
<# if 条件>
输出
<#elseif 条件>
输出
<#else>
输出
</#if>
----------------------------------------------
<# switch var(可为字符串)>
<#case 条件1>
输出
<#break>
<#case 条件2>
输出
<#break>
<#default>
输出
</#switch>
list指令
基本使用
<#-- 语法一 -->
<#list sequence as item>
有迭代数据时输出
<#else>
没有迭代数据时输出
<#list>
<#-- 语法二 避免输出空标签-->
<#list sequence>
<#items as item>
有迭代数据时输出
</#items>
<#else>
没有迭代数据时输出
<#list>
输出结果显示(比如拼接逗号)
<sep>:
在后面是<list>标签时可简写:
<#list users as user>${user}<#sep>,</#list>,
而如果后面跟着的时<div>等标签,需要写全:
<#list users as user>${user}<#sep>,</#sep></#list>
list中的排序:
sort_by() <#-- 升序-->
sort_by()?reverse <#-- 降序-->
<#list users?sort as user>${user}</#list>
<#list users?sort_by("age") as user>${user.name}-${user.age}</#list>
<#list users?sort_by("age")?reverse as user>${user.name}-${user.age}</#list>
list遍历map
<#list dataMap?keys as key>
${key}-${dataMap[key]}
</#list>
FreeMarker内建函数
所谓内建函数,就是由语法规定存在的函数。是不需要引入任何外部资源就可以使用的函数。
像上面介绍的sep标签使用内建函数的形式来书写就是:
<#list users as user>${user}<#if user?has_next>,</#if></#list>
诸如sort_by、reverse、has_next都是内建函数,有关内建函数的使用参考官方文档,实际开发中使用到了直接按类型查找即可
FreeMarker实例
最后给出一段入门级代码,通过FreeMarker生成html文件
public class FreeMarkerToHtml {
// step1:设置模板文件的存放位置以及生成文件的存放位置
private static final String TEMPLATE_PATH="src/main/resources/templates";
private static final String CLASS_PATH="src/main/resources/templates";
//step2: 构建Freemarker的实例对象
public static void main(String[] args) throws IOException, TemplateException {
Configuration configuration = new Configuration(Configuration.VERSION_2_3_0);
configuration.setDefaultEncoding("utf-8");
configuration.setDirectoryForTemplateLoading(new File(TEMPLATE_PATH));
//step3:创建数据模型
Map<String,Object> dataMap = new HashMap<String, Object>();
dataMap.put("name","张三");
//step4:加载模板文件
Template template = configuration.getTemplate("welcome.ftl");
//step5:构建输出对象
File docFile = new File(CLASS_PATH+"\\"+"welcom.html");
Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(docFile)));
//step6:输出文件
template.process(dataMap,writer);
System.out.println("文件创建成功");
//step7:关流
writer.close();
}
}