初识Freemarker

1.Freemarker定义

FreeMarker是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页、电子邮件、配置文件、源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员能够嵌入他们所开发产品的组件。
FreeMarker是免费的,基于Apache许可证2.0版本发布。其模板编写为FreeMarker Template Language(FTL),属于简单、专用的语言。须要准备数据在真实编程语言中来显示,好比数据库查询和业务运算, 以后模板显示已经准备好的数据。在模板中,主要用于如何展示数据, 而在模板以外注意于要展现什么数据。html

最新版本FreeMarker 2.3.23。java

2.工做原理

  请看下面代码:python

复制代码
<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命令的页面内容。程序员

  以上为模板准备的数据称为数据模型。它是一种树形结构(相似硬盘的文件夹和文件的关系)。  web

复制代码
(root)
  |
  +- user = "Big Joe"
  |
  +- latestProduct
      |
      +- url = "products/greenmouse.html"
      |
      +- name = "green mouse"
复制代码

  

  早期版本中,能够从数据模型中选取这些值,使用user和latestProduct.name表达式便可。类比于硬盘的树形结构,数据模型就像一个文件系统,“(root)”和latestProduct就对应着目录(文件夹),而user、url和name就是这些目录中的文件。
整体上,模板和数据模型是FreeMarker来生成输出所必须的组成部分:模板 + 数据模型 = 输出

3.基本语法

  • ${...}:FreeMarker将会输出真实的值来替换大括号内的表达式,这样的表达式被称为interpolation(插值)。
  • 注释:注释和HTML的注释也很类似,可是它们使用<#-- and -->来标识。不像HTML注释那样,FTL注释不会出如今输出中(不出如今访问者的页面中),由于FreeMarker会跳过它们。
  • 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循环之中的例子,能够为每一个循环周期内指定不一样的文件名 。浏览器

  空变量    

  数据模型中常常会有可选的变量(有时并不存在)。除了一些人为缘由致使失误外,FreeMarker不能引用不存在的变量,除非明确地告诉它当变量不存在时如何处理,以下两种典型的处理方法:
这部分对程序员而言:一个不存在的变量和一个是null的变量,对于FreeMarker来讲是同样的,因此这里所指的“丢失”包含这两种状况。
不论在哪里引用变量,均可以指定一个默认值来避免变量丢失这种状况,经过在变量名后面跟着一个 !和默认值。像下面的这个例子,当user不存在于数据模型时,模板将会将user的值表示为字符串 “visitor”。(当 user 存在时,模板就会表现出 ${user} 的值):
1
< h1 >Welcome ${user!"visitor"}!</ h1 >
也能够在变量名后面经过放置??来询问一个变量是否存在。将它和if指令合并,那么若是user变量不存在的话将会忽略整个问候的代码段:
1
2
3
< #if user??>
     <h1>Welcome ${user}!< /h1 >
</ #if>
  关于多级访问的变量,好比 animals.python.price,书写代码:animals.python.price!0当且仅当animals.python永远存在,而仅仅最后一个子变量price可能不存在时是正确的(这种状况下假设价格是0)。若是 animals或python不存在,那么模板处理过程将会以“未定义的变量”错误而中止。为了防止这种状况的发生, 能够以下这样来编写代码 (animals.python.price)!0。这种状况就是说animals或python不存在时,表达式的结果是 0。对于??也是一样用来的处理这种逻辑的;将animals.python.price??对比(animals.python.price)??来看。

4.性能特色

  基于MVC模式实现,显示逻辑与业务逻辑分离,便于理解,提升我的专一性。缓存

  4.1. 通用性
  可以生成各类文本:HTMLXMLRTF、Java源代码等等。
  易于嵌入到产品中:轻量级;不须要Servlet环境。
  插件式模板载入器:能够从任何源载入模板,如本地文件、数据库等等。
  能够按所需生成文本:保存到本地文件;做为Email发送;从Web应用程序发送它返回给Web浏览器。

  4.2. 模板语言
  全部经常使用的指令:include、if/elseif/else、循环结构
  在模板中建立和改变变量。
  几乎在任何地方均可以使用复杂表达式来指定值。
  命名的宏,能够具备位置参数和嵌套内容。
  名字空间有助于创建和维护可重用的宏库,或者将一个大工程分红模块,而没必要担忧名字冲突。
  输出转换块:在嵌套模板片断生成输出时,转换HTML转义、压缩、语法高亮等等;能够定义本身的转换。

4.3. 通用数据模型
  FreeMarker不是直接反射到Java对象,Java对象经过插件式对象封装,以变量方式在模板中显示。
  可使用抽象(接口)方式表示对象( JavaBeanXML文档、 SQL查询结果集等等),告诉模板开发者使用。方法,使其不受技术细节的打扰。
  xml配置
4.4. 为Web准备
  在模板语言中内建处理典型Web相关任务(如 HTML转义)的结构。
  可以集成到Model2 Web应用框架中做为JSP的替代。
  支持JSP标记库。
  为MVC模式设计:分离可视化设计和应用程序逻辑;分离页面设计员和程序员。
4.5. 智能的国际化和本地化
  字符集智能化(内部使用 UNICODE)。
  数字格式本地化敏感。
  日期和时间格式本地化敏感。
  非US 字符集能够用做标识(如变量名)。
  多种不一样语言的相同模板。
4.6. XML处理能力
  <#recurse> 和<#visit>指令(2.3版本)用于递归遍历 XML树。
  在模板中清楚和直接的访问XML 对象模型 。

5.Freemarker与JSP、velocity的比较

5.1. JSP优势:
一、功能强大,能够写java代码
二、支持jsp标签(jsp tag)
三、支持表达式语言(el)
四、官方标准,用户群广,丰富的第三方jsp标签库
五、性能良好。jsp编译成class文件执行,有很好的性能表现
缺点:
复杂页面使用效率低;使用不当容易破坏mvc结构。

5.2. velocity优势:
一、不能编写java代码,能够实现严格的mvc分离
二、性能良好,听说比jsp性能还要好些
三、使用表达式语言,听说jsp的表达式语言就是学velocity的
缺点:
一、不是官方标准
二、用户群体和第三方标签库没有jsp多。
三、对jsp标签支持不够好。

6.总结

  Freemarker

  优势:

  6.1. 先后端分离

  6.2. freemarker模板能够在servlet以外使用,不须要使用类加载器加载,可使用它们来生成电子邮件、 配置文件、 XML 映射等。

  6.3. 高并发下能够设置页面静态化缓存提升查询性能

  缺点:

  6.4. 不是官方标准,支持的JSP标签库少。

  6.5. FreeMarker中的变量必需要赋值,模板发生变化时容易看到过时数据。