初识Freemarker
1.Freemarker定义
FreeMarker是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页、电子邮件、配置文件、源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。
FreeMarker是免费的,基于Apache许可证2.0版本发布。其模板编写为FreeMarker Template Language(FTL),属于简单、专用的语言。需要准备数据在真实编程语言中来显示,比如数据库查询和业务运算, 之后模板显示已经准备好的数据。在模板中,主要用于如何展现数据, 而在模板之外注意于要展示什么数据。
最新版本FreeMarker 2.3.23。
2.工作原理
请看下面代码:
- <html>
- <head>
- <title>Welcome!</title>
- </head>
- <body>
- <h1>Welcome ${user}!</h1>
- <p>Our latest product:
- <a href="${latestProduct.url}">${latestProduct.name}</a>!
- </body>
- </html>
模板文件保存在WEB服务器上,当有人访问这个页面时,Freemarker就会发出响应,动态转换模板中${..}的部分,之后将结果发送到访问者的web浏览器中,浏览器端看到的内容会是没有Freemarker命令的页面内容。
以上为模板准备的数据称为数据模型。它是一种树形结构(类似硬盘的文件夹和文件的关系)。
- (root)
- |
- +- user = "Big Joe"
- |
- +- latestProduct
- |
- +- url = "products/greenmouse.html"
- |
- +- name = "green mouse"
3.基本语法
-
${…}:FreeMarker将会输出真实的值来替换大括号内的表达式,这样的表达式被称为interpolation(插值)。
-
FTL标签(FreeMarker模板的语言标签):FTL标签和HTML标签有一些相似之处,但是它们是FreeMarker的指令,是不会在输出中打印的。这些标签的名字以#开头。(用户自定义的FTL标签则需要使用@来代替#
指令
- <#if condition>
- ...
- <#elseif condition2>
- ...
- <#elseif condition3>
- ...
- <#else>
- ...
- </#if>
if、elseif和else指令可以用来条件判断是否越过模板的一个部分。condition必须计算成布尔值,否则错误将会中止模板处理。elseif和else必须出现在if内部(也就是在if的开始标签和结束标签之间)。if中可以包含任意数量的elseif(包括0个),而结束时else也是可选的。
- 假设 users 包含[\'Joe\', \'Kate\', \'Fred\'] 序列:
- <#list users as user>
- <p>${user}
- </#list>
- 输出:
- <p>Joe
- <p>Kate
- <p>Fred
list指令执行在list开始标签和list结束标签(list中间的部分)之间的代码,对于在序列(或集合)中每个值指定为它的第一个参数。对于每次
迭代,循环变量将会存储当前项的值。循环变量仅仅存在于list标签体内。而且从循环中调用的宏/函数不会看到它(就像它只是局部变量一样)。
<#list>与<#else>、<#sep>组合是可选的,而且仅从FreeMarker 2.3.23版本开始支持 。
- 将版权信息单独存放在页面文件 copyright_footer.html 中:
- <hr>
- <i>
- Copyright (c) 2000 <a href="http://www.baidu.com">Baidu Inc</a>,
- <br>
- All Rights Reserved.
- </i>
- 当需要用到这个文件时,可以使用 include 指令来插入:
- <html>
- <head>
- <title>Test page</title>
- </head>
- <body>
- <h1>Test page</h1>
- <p>Blah blah...
- <#include "/copyright_footer.html">
- </body>
- </html>
include可以在模板中插入另外一个FreeMarker模板文件(由路径参数指定)。被包含模板的输出格式是在include标签出现的位置插入的。被包含
的文件和包含它的模板共享变量,就像是被复制粘贴进去的一样。include指令不能由被包含文件的内容所替代,它只是当FreeMarker每次在模板处
理期间到达include指令时处理被包含的文件。所以对于如果include在list循环之中的例子,可以为每个循环周期内指定不同的文件名 。
空变量
1
|
< h1 >Welcome ${user!"visitor"}!</ h1 >
|
1
2
3
|
< #if user??>
<h1>Welcome ${user}!< /h1 >
</ #if>
|
4.性能特点
基于MVC模式实现,显示逻辑与业务逻辑分离,便于理解,提高个人专注性。
4.1. 通用性
能够生成各种文本:HTML、XML、RTF、Java源代码等等。
易于嵌入到产品中:轻量级;不需要Servlet环境。
插件式模板载入器:可以从任何源载入模板,如本地文件、数据库等等。
可以按所需生成文本:保存到本地文件;作为Email发送;从Web应用程序发送它返回给Web浏览器。
4.2. 模板语言
所有常用的指令:include、if/elseif/else、循环结构。
在模板中创建和改变变量。
几乎在任何地方都可以使用复杂表达式来指定值。
命名的宏,可以具有位置参数和嵌套内容。
名字空间有助于建立和维护可重用的宏库,或者将一个大工程分成模块,而不必担心名字冲突。
输出转换块:在嵌套模板片段生成输出时,转换HTML转义、压缩、语法高亮等等;可以定义自己的转换。
FreeMarker不是直接反射到Java对象,Java对象通过插件式对象封装,以变量方式在模板中显示。
可以使用抽象(接口)方式表示对象(JavaBean、XML文档、SQL查询结果集等等),告诉模板开发者使用。方法,使其不受技术细节的打扰。
4.4. 为Web准备
在模板语言中内建处理典型Web相关任务(如HTML转义)的结构。
能够集成到Model2 Web应用框架中作为JSP的替代。
支持JSP标记库。
为MVC模式设计:分离可视化设计和应用程序逻辑;分离页面设计员和程序员。
5.Freemarker与JSP、velocity的比较
5.1. JSP优点:
1、功能强大,可以写java代码
2、支持jsp标签(jsp tag)
3、支持表达式语言(el)
4、官方标准,用户群广,丰富的第三方jsp标签库
5、性能良好。jsp编译成class文件执行,有很好的性能表现
缺点:
复杂页面使用效率低;使用不当容易破坏mvc结构。
5.2. velocity优点:
1、不能编写java代码,可以实现严格的mvc分离
2、性能良好,据说比jsp性能还要好些
3、使用表达式语言,据说jsp的表达式语言就是学velocity的
缺点:
1、不是官方标准
2、用户群体和第三方标签库没有jsp多。
3、对jsp标签支持不够好。
6.总结
Freemarker
优点:
6.1. 前后端分离
6.2. freemarker模板可以在servlet之外使用,不需要使用类加载器加载,可以使用它们来生成电子邮件、 配置文件、 XML 映射等。
6.3. 高并发下可以设置页面静态化缓存提高查询性能
缺点:
6.4. 不是官方标准,支持的JSP标签库少。
6.5. FreeMarker中的变量必须要赋值,模板发生变化时容易看到过期数据。