赞
踩
FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。
模板编写为FreeMarker Template Language (FTL)。它是简单的,专用的语言, 不是 像PHP那样成熟的编程语言。 那就意味着要准备数据在真实编程语言中来显示,比如数据库查询和业务运算, 之后模板显示已经准备好的数据。在模板中,你可以专注于如何展现数据, 而在模板之外可以专注于要展示什么数据。
目前企业中:主要用Freemarker做静态页面或是页面展示
这种方式通常被称为 MVC (模型 视图 控制器) 模式,对于动态网页来说,是一种特别流行的模式。 它帮助从开发人员(Java 程序员)中分离出网页设计师(HTML设计师)。设计师无需面对模板中的复杂逻辑, 在没有程序员来修改或重新编译代码时,也可以修改页面的样式。
而FreeMarker最初的设计,是被用来在MVC模式的Web开发框架中生成HTML页面的,它没有被绑定到 Servlet或HTML或任意Web相关的东西上。它也可以用于非Web应用环境中。
创建maven工程并导入Freemarker的maven坐标
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>
模板文件中有四种元素:
文本:文本会照着原样来输出。
插值:这部分的输出会被计算的值来替换。插值由 ${ and } 所分隔(或者 #{ and },这种风格已经不建议再使用了)。
FTL 标签:FTL标签和HTML标签很相似,但是它们却是给FreeMarker的指示, 而且不会打印在输出内容中。
注释:注释和HTML的注释也很相似,但它们是由 <#-- 和 -->来分隔的。注释会被FreeMarker直接忽略, 更不会在输出内容中显示。
Freemarker的模板文件后缀可以任意,一般建议为ftl。
我们来看一个具体的模板。其中的内容已经用颜色来标记了: 文本, 插值, FTL 标签, 注释。为了看到可见的 换行符, 这里使用了 [BR]。
我们来看一个具体的模板。其中的内容已经用颜色来标记了: 文本, 插值, FTL 标签, 注释。
<html>
<head>
<title>Welcome!</title>
</head>
<body>
<#-- Greet the user with his/her name -->
<h1>Welcome ${user}!</h1>
<p>We have these animals:
<ul>
<#list animals as animal>
<li>${animal.name} for ${animal.price} Euros
</#list>
</ul>
</body>
</html>
FTL是区分大小写的。 list 是指令的名称而 List 就不是。类似地 ${name} 和 ${Name} 或 ${NAME} 也是不同的。
请注意非常重要的一点: 插值 仅仅可以在 文本 中使用。 (也可以是字符串表达式)
FTL 标签 不可以在其他 FTL 标签 和 插值中使用。比如, 这样做是 错误 的: <#if <#include 'foo'>='bar'>...</#if>
注释 可以放在 FTL 标签 和 插值中。比如:
<h1>Welcome ${user <#-- The name of user -->}!</h1>
<p>We have these animals:
<ul>
<#list <#-- some comment... --> animals as <#-- again... --> animal>
...
使用步骤:
第一步:创建一个 Configuration 对象,直接 new 一个对象。构造方法的参数就是 freemarker的版本号。
第二步:设置模板文件所在的路径。
第三步:设置模板文件使用的字符集。一般就是 utf-8。
第四步:加载一个模板,创建一个模板对象。
第五步:创建一个模板使用的数据集,可以是 pojo 也可以是map。一般是 Map。
第六步:创建一个 Writer 对象,一般创建 FileWriter 对象,指定生成的文件名。
第七步:调用模板对象的 process 方法输出文件。
第八步:关闭流。
模板文件 test.ftl
<html>
<head>
<meta charset="utf-8">
<title>Freemarker入门</title>
</head>
<body>
<#--我只是一个注释,我不会有任何输出 -->
${name}你好,${message}
</body>
</html>
java文件
public static void main(String[] args) throws Exception{ //1.创建配置类 Configuration configuration=new Configuration(Configuration.getVersion()); //2.设置模板所在的目录 configuration.setDirectoryForTemplateLoading(new File("D:\\ftl")); //3.设置字符集 configuration.setDefaultEncoding("utf-8"); //4.加载模板 Template template = configuration.getTemplate("test.ftl"); //5.创建数据模型 Map map=new HashMap(); map.put("name", "张三"); map.put("message", "欢迎来到私忆一秒钟的博客!"); //6.创建Writer对象 Writer out =new FileWriter(new File("d:\\test.html")); //7.输出 template.process(map, out); //8.关闭Writer对象 out.close(); }
运行结果生成:test.html文件
assign指令用于在页面上定义一个变量
<#assign linkman="私忆一秒钟">
联系人:${linkman}
<#assign info={"mobile":"123456789",'address':'地球'}>
电话:${info.mobile} 地址:${info.address}
if指令用于判断
<#if success=true>
你已通过实名认证
<#else>
你未通过实名认证
</#if>
map.put("success", true);
在freemarker的判断中,可以使用=也可以使用==
list指令用于遍历
<#list goodsList as goods>
<li>${goods.name} , ${goods.price}
</#list>
List goodsList=new ArrayList(); Map goods1=new HashMap(); goods1.put("name", "苹果"); goods1.put("price", 5.8); Map goods2=new HashMap(); goods2.put("name", "香蕉"); goods2.put("price", 2.5); Map goods3=new HashMap(); goods3.put("name", "橘子"); goods3.put("price", 3.2); goodsList.add(goods1); goodsList.add(goods2); goodsList.add(goods3); map.put("goodsList", goodsList);
include指令用于模板文件的嵌套
<#include "test.ftl">
在页面上也可以多次使用指令,而且指令间也可以很容易地相互嵌套。 比如,在 list 指令中嵌套 if 指令:
<#list animals as animal>
<div<#if animal.protected> class="protected"</#if>>
${animal.name} for ${animal.price} Euros
</div>
</#list>
请注意,FreeMarker并不解析FTL标签以外的文本、插值和注释, 上面示例在HTML属性中使用FTL标签也不会有问题。
内建函数很像子变量(如果了解Java术语的话,也可以说像方法), 它们并不是数据模型中的东西,是 FreeMarker 在数值上添加的。 为了清晰子变量是哪部分,使用 ?(问号)代替 .(点)来访问它们。常用内建函数的示例:
user?html
给出 user 的HTML转义版本, 比如 &
会由 &
来代替。
user?upper_case
给出 user 值的大写版本 (比如 “JOHN DOE” 来替代 “John Doe”)
animal.name?cap_first
给出 animal.name 的首字母大写版本(比如 “Mouse” 来替代 “mouse”)
user?length
给出 user 值中 字符的数量(对于 “John Doe” 来说就是8)
animals?size
给出 animals 序列中 项目 的个数(我们示例数据模型中是3个)
如果在 <#list animals as animal>
和对应的 </#list>
标签中:
animal?index
给出了在 animals 中基于0开始的 animal的索引值
animal?counter
也像 index, 但是给出的是基于1的索引值
animal?item_parity
基于当前计数的奇偶性,给出字符串 “odd” 或 “even”。在给不同行着色时非常有用,比如在 <td class="${animal?item_parity}Row">
中。
一些内建函数需要参数来指定行为,比如:
animal.protected?string("Y", "N")
基于 animal.protected 的布尔值来返回字符串 “Y” 或 “N”。
animal?item_cycle('lightRow','darkRow')
是之前介绍的 item_parity 更为常用的变体形式。
fruits?join(", ")
通过连接所有项,将列表转换为字符串, 在每个项之间插入参数分隔符(比如 “orange,banana”)
user?starts_with("J")
根据 user 的首字母是否是 “J” 返回布尔值true或false。
内建函数应用可以链式操作,比如user?upper_case?html 会先转换用户名到大写形式,之后再进行HTML转义。(这就像可以链式使用 .(点)一样)
数据模型中经常会有可选的变量(也就是说有时并不存在)。 除了一些典型的人为原因导致失误外,FreeMarker 绝不能容忍引用不存在的变量, 除非明确地告诉它当变量不存在时如何处理。这里来介绍两种典型的处理方法。
这部分对程序员而言: 一个不存在的变量和一个是 null 值的变量, 对于FreeMarker来说是一样的,所以这里所指的"丢失"包含这两种情况。
不论在哪里引用变量,都可以指定一个默认值来避免变量丢失这种情况, 通过在变量名后面跟着一个 !(叹号)和默认值。 就像下面的这个例子,当 user 不存在于数据模型时, 模板将会将 user 的值表示为字符串 “visitor”。(当 user 存在时, 模板就会表现出 ${user} 的值):
<h1>Welcome ${user!"visitor"}!</h1>
也可以在变量名后面通过放置 ?? 来询问一个变量是否存在。将它和 if 指令合并, 那么如果 user 变量不存在的话将会忽略整个问候的代码段:
<#if user??><h1>Welcome ${user}!</h1></#if>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。