学习笔记,选自freeMarker中文文档,译自 Email: ddekany at users.sourceforge.net

1.创建Configuration实例

  首先,你应该创建一个 freemarker.template.Configuration 实例, 然后调整它的设置。Configuration 实例是存储 FreeMarker 应用级设置的核心部分。同时,它也处理创建和 缓存 预解析模板(比如 Template 对象)的工作。

  也许你只在应用(可能是servlet)生命周期的开始执行一次

 // Create your Configuration instance, and specify if up to what FreeMarker
 // version (here 2.3.22) do you want to apply the fixes that are not 100%
 // backward-compatible. See the Configuration JavaDoc for details.
 Configuration cfg = new Configuration(Configuration.VERSION_2_3_22);

 // Specify the source where the template files come from. Here I set a
 // plain directory for it, but non-file-system sources are possible too:
 cfg.setDirectoryForTemplateLoading(new File("/where/you/store/templates"));

 // Set the preferred charset template files are stored in. UTF-8 is
 // a good choice in most applications:
 cfg.setDefaultEncoding("UTF-8");

 // Sets how errors will appear.
 // During web page *development* TemplateExceptionHandler.HTML_DEBUG_HANDLER is better.
 cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);

  从现在开始,应该使用单实例配置(也就是说,它是单例的)。 请注意不管一个系统有多少独立的组件来使用 FreeMarker, 它们都会使用他们自己私有的 Configuration 实例。

警告:不需要重复创建 Configuration 实例; 它的代价很高,尤其是会丢失缓存。Configuration 实例就是应用级别的单例。

  当使用多线程应用程序(比如Web网站),Configuration 实例中的设置就不能被修改。它们可以被视作为 "有效的不可改变的" 对象, 也可以继续使用 安全发布 技术 (参考 JSR 133 和相关的文献)来保证实例对其它线程也可用。比如, 通过final或volatile字段来声明实例,或者通过线程安全的IoC容器,但不能作为普通字段。 (Configuration 中不处理修改设置的方法是线程安全的。)

2.创建数据模型

  在简单的示例中你可以使用 java.langjava.util 包中的类, 还有用户自定义的Java Bean来构建数据对象:

  • 使用 java.lang.String 来构建字符串。

  • 使用 java.lang.Number 来派生数字类型。

  • 使用 java.lang.Boolean 来构建布尔值。

  • 使用 java.util.List 或Java数组来构建序列。

  • 使用 java.util.Map 来构建哈希表。

  • 使用自定义的bean类来构建哈希表,bean中的项和bean的属性对应。比如, productprice 属性 (getProperty())可以通过 product.price 获取。(bean的action也可以通过这种方式拿到; 要了解更多可以参看 这里)

  我们为 模板开发指南部分演示的第一个例子 来构建数据模型。为了方便说明,这里再展示一次示例:

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

  下面是构建这个数据模型的Java代码片段:

 // Create the root hash
 Map<String, Object> root = new HashMap<>();
 // Put string ``user'' into the root
 root.put("user", "Big Joe");
 // Create the hash for ``latestProduct''
 Map<String, Object> latest = new HashMap<>();
 // and put it into the root
 root.put("latestProduct", latest);
 // put ``url'' and ``name'' into latest
 latest.put("url", "products/greenmouse.html");
 latest.put("name", "green mouse");

  在真实应用系统中,通常会使用应用程序指定的类来代替 Map, 它会有JavaBean规范规定的 getXxx/isXxx 方法。比如有一个和下面类似的类:

 public class Product {

     private String url;
     private String name;
     ...

     // As per the JavaBeans spec., this defines the "url" bean property
     public String getUrl() {
         return url;
     }

     // As per the JavaBean spec., this defines the "name" bean property
     public String getName() {
         return name;
     }

     ...

 }

  将它的实例放入数据模型中,就像下面这样:

 Product latestProducts = getLatestProductFromDatabaseOrSomething();
 root.put("latestProduct", latestProduct);

  如果latestProductMap类型, 模板就可以是相同的,比如 ${latestProduct.name} 在两种情况下都好用。

  根root本身也无需是 Map,只要是有 getUser()getLastestProduct() 方法的对象即可。

注意:如果配置设置项 object_wrapper 的值是用于所有真实步骤, 这里描述的行为才好用。任何由 ObjectWrapper 包装成的哈希表 可以用作根root,也可以在模板中和点、 [] 操作符使用。 如果不是包装成哈希表的对象不能作为根root,也不能像那样在模板中使用。

3.获取模板

  模板代表了 freemarker.template.Template 实例。典型的做法是从 Configuration 实例中获取一个 Template 实例。无论什么时候你需要一个模板实例, 都可以使用它的 getTemplate 方法来获取。在 之前 设置的目录中的 test.ftl 文件中存储 示例模板,那么就可以这样来做:

Template temp = cfg.getTemplate("test.ftl");

  当调用这个方法的时候,将会创建一个 test.ftlTemplate 实例,通过读取 /where/you/store/templates/test.ftl 文件,之后解析(编译)它。Template 实例以解析后的形式存储模板, 而不是以源文件的文本形式。

  Configuration 缓存 Template 实例,当再次获得 test.ftl 的时候,它可能再读取和解析模板文件了, 而只是返回第一次的 Template 实例。

4.合并模板和数据模型

  我们已经知道,数据模型+模板=输出,我们有了一个数据模型 (root) 和一个模板 (temp), 为了得到输出就需要合并它们。这是由模板的 process 方法完成的。它用数据模型root和 Writer 对象作为参数,然后向 Writer 对象写入产生的内容。 为简单起见,这里我们只做标准的输出:

 Writer out = new OutputStreamWriter(System.out);
 temp.process(root, out);

  这会向你的终端输出你在模板开发指南部分的 第一个示例 中看到的内容。

  Java I/O 相关注意事项:基于 out 对象,必须保证 out.close() 最后被调用。当 out 对象被打开并将模板的输出写入文件时,这是很电影的做法。其它时候, 比如典型的Web应用程序,那就 不能 关闭 out 对象。FreeMarker 会在模板执行成功后 (也可以在 Configuration 中禁用) 调用 out.flush(),所以不必为此担心。

  请注意,一旦获得了 Template 实例, 就能将它和不同的数据模型进行不限次数 (Template实例是无状态的)的合并。此外, 当 Template 实例创建之后 test.ftl 文件才能访问,而不是在调用处理方法时。

5.将代码放在一起

  这是一个由之前的代码片段组合在一起的源程序文件。 千万不要忘了将 freemarker.jar 放到 CLASSPATH 中。

 import freemarker.template.*;
 import java.util.*;
 import java.io.*;

 public class Test {

     public static void main(String[] args) throws Exception {

         /* ------------------------------------------------------------------------ */
         /* You should do this ONLY ONCE in the whole application life-cycle:        */    

         /* Create and adjust the configuration singleton */
         Configuration cfg = new Configuration(Configuration.VERSION_2_3_22);
         cfg.setDirectoryForTemplateLoading(new File("/where/you/store/templates"));
         cfg.setDefaultEncoding("UTF-8");
         cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW);

         /* ------------------------------------------------------------------------ */
         /* You usually do these for MULTIPLE TIMES in the application life-cycle:   */    

         /* Create a data-model */
         Map root = new HashMap();
         root.put("user", "Big Joe");
         Map latest = new HashMap();
         root.put("latestProduct", latest);
         latest.put("url", "products/greenmouse.html");
         latest.put("name", "green mouse");

         /* Get the template (uses cache internally) */
         Template temp = cfg.getTemplate("test.ftl");

         /* Merge data-model with template */
         Writer out = new OutputStreamWriter(System.out);
         temp.process(root, out);
         // Note: Depending on what `out` is, you may need to call `out.close()`.
         // This is usually the case for file output, but not for servlet output.
     }
 }
注意:为了简单起见,这里压制了异常(在方法签名中声明了异常), 而在正式运行的产品中不要这样做。
 
译自 Email: ddekany at users.sourceforge.net

freeMarker(六)——程序开发指南入门的更多相关文章

  1. python 整型--《Python 3程序开发指南》笔记

    参考:<Python 3程序开发指南> 整数转换函数: bin(i) 返回整数i的二进制表示(字符串) hex(i) 返回i的十六进制表示(字符串) int(x) 将x转换为整数,失败产生 ...

  2. freeMarker(八)——程序开发指南之配置(Configuration)

    学习笔记,选自freeMarker中文文档,译自 Email: ddekany at users.sourceforge.net 1.基本内容 配置(configuration)就是 freemark ...

  3. FreeMarker:模板开发指南

    ylbtech-FreeMarker:模板开发指南 1.返回顶部 1. Section Contents 入门 模板 + 数据模型 = 输出 数据模型一览 模板一览 数值,类型 基本内容 类型 模板 ...

  4. 微信小程序开发之入门篇(熟悉开发工具)

    个人的每一篇博文都谈不上有什么技术含量,只是为了帮助不熟悉微信小程序开发的自己及他人提供一下思路.谢谢,下面开始! PS: 因为本人没有小程序的内测资格,所以所有的开发及Demo都是无AppId的,如 ...

  5. freeMarker(九)——程序开发指南补充知识

    学习笔记,选自freeMarker中文文档,译自 Email: ddekany at users.sourceforge.net 1.变量.范围 本章介绍当模板在访问变量时发生了什么事情,还有变量是如 ...

  6. freeMarker(七)——程序开发指南之数据模型

    学习笔记,选自freeMarker中文文档,译自 Email: ddekany at users.sourceforge.net 1.基本内容 在入门章节中, 我们已经知道如何使用基本的Java类(M ...

  7. 微信小程序 - 开发指南

    一.下载并安装开发工具 下载地址 二.创建项目 打开开发工具 添加项目 进入预览和调试界面 代码编辑器 编译并预览 三.启动流程 四.适用场景 五.技术框架 六.科普 [图片较大 - 点击查看]

  8. QtQuick桌面应用程序开发指南 4)动态管理Note对象_B 5)加强外观 6)许多其他的改进

    4.2.2 Stateless(不管状态)JavaScript库 为了让开发轻松点, 使用一个JavaScript接口来和数据库交互是个好主意, 它在QML中提供了方便的方法; 在QtCreator中 ...

  9. 微信小程序开发之入门篇(熟悉项目结构)

    微信小程序创建之后会生成一个项目模板,如下图所示(基本如此,但并不局限于此) 现在分别来说明一下每个文件及目录的意思 app.js 程序的入口文件,必须存在. app.js是小程序的脚本代码.我们可以 ...

随机推荐

  1. solr查询

    1.根据字段查询: http://www.360doc.com/content/14/0306/18/203871_358295621.shtml 2.模糊查询: http://www.tuicool ...

  2. 九度OJ 1341:艾薇儿的演唱会 (最短路)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:528 解决:241 题目描述: 艾薇儿今天来到了中国,她计划两天后在哈尔滨举行一场个人的演唱会.由于出现了紧急情况,演唱会的举办方要求艾薇儿 ...

  3. 我的Android进阶之旅------>四种呼叫转移场景

    运行商为我们提供了如下4中呼叫转移场景: 1.始终进行呼叫转移:不管当前手机处于何种状态,来电都会被转移到指定的电话号码上.在使用这种呼叫转移时应当非常小心,如果启用了这种呼叫转移,你可就永远也接不着 ...

  4. linux 10 -Bash Shell编程

    二十三. Bash Shell编程:     1.  读取用户变量:     read命令是用于从终端或者文件中读取输入的内建命令,read命令读取整行输入,每行末尾的换行符不被读入.在read命令后 ...

  5. R语言做正态性检验

    摘自:吴喜之:<非参数统计>(第二版),中国统计出版社,2006年10月:P164-165 1.ks.test()    例如零假设为N(15,0.2),则ks.test(x," ...

  6. 分布式文件存储——GlusterFS

    一.概论 1.简介 GlusterFS (Gluster File System) 是一个开源的分布式文件系统,主要由 Z RESEARCH 公司负责开发. GlusterFS 是 Scale-Out ...

  7. Java中的 && 与&

    Java中&&和&都是表示与的逻辑运算符,都表示逻辑运输符and,当两边的表达式都为true的时候,整个运算结果才为true,否则为false. &&的短路功能 ...

  8. Yii2 高级查询

    首先我们要自己写一个ActiveQuery 类并且继承 Yii2 的 ActiveQuery: namespace api\models; class ActiveQuery extends \yii ...

  9. BOM之history

    history是JavaScript中BOM上的一个对象,其中存储了浏览器的历史记录 history存储简单过程 浏览器会将一个窗口中访问的网页进行记录,不管我们通过以下哪种方式改变页面,浏览器都会把 ...

  10. 剑指offer之 二进制中1的个数

    问题描述: 请实现一个函数,输入一个整数,输出该数二进制表示中1的个数.例如把9表示成二进制是1001,有2位是1 因此如果输入9,该函数输出2; package Problem10; public ...