freeMarker(六)——程序开发指南入门
学习笔记,选自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.lang
和 java.util
包中的类, 还有用户自定义的Java Bean来构建数据对象:
使用
java.lang.String
来构建字符串。使用
java.lang.Number
来派生数字类型。使用
java.lang.Boolean
来构建布尔值。使用
java.util.List
或Java数组来构建序列。使用
java.util.Map
来构建哈希表。使用自定义的bean类来构建哈希表,bean中的项和bean的属性对应。比如,
product
的price
属性 (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);
如果latestProduct
是 Map
类型, 模板就可以是相同的,比如 ${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.ftl
的 Template
实例,通过读取 /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. } }
freeMarker(六)——程序开发指南入门的更多相关文章
- python 整型--《Python 3程序开发指南》笔记
参考:<Python 3程序开发指南> 整数转换函数: bin(i) 返回整数i的二进制表示(字符串) hex(i) 返回i的十六进制表示(字符串) int(x) 将x转换为整数,失败产生 ...
- freeMarker(八)——程序开发指南之配置(Configuration)
学习笔记,选自freeMarker中文文档,译自 Email: ddekany at users.sourceforge.net 1.基本内容 配置(configuration)就是 freemark ...
- FreeMarker:模板开发指南
ylbtech-FreeMarker:模板开发指南 1.返回顶部 1. Section Contents 入门 模板 + 数据模型 = 输出 数据模型一览 模板一览 数值,类型 基本内容 类型 模板 ...
- 微信小程序开发之入门篇(熟悉开发工具)
个人的每一篇博文都谈不上有什么技术含量,只是为了帮助不熟悉微信小程序开发的自己及他人提供一下思路.谢谢,下面开始! PS: 因为本人没有小程序的内测资格,所以所有的开发及Demo都是无AppId的,如 ...
- freeMarker(九)——程序开发指南补充知识
学习笔记,选自freeMarker中文文档,译自 Email: ddekany at users.sourceforge.net 1.变量.范围 本章介绍当模板在访问变量时发生了什么事情,还有变量是如 ...
- freeMarker(七)——程序开发指南之数据模型
学习笔记,选自freeMarker中文文档,译自 Email: ddekany at users.sourceforge.net 1.基本内容 在入门章节中, 我们已经知道如何使用基本的Java类(M ...
- 微信小程序 - 开发指南
一.下载并安装开发工具 下载地址 二.创建项目 打开开发工具 添加项目 进入预览和调试界面 代码编辑器 编译并预览 三.启动流程 四.适用场景 五.技术框架 六.科普 [图片较大 - 点击查看]
- QtQuick桌面应用程序开发指南 4)动态管理Note对象_B 5)加强外观 6)许多其他的改进
4.2.2 Stateless(不管状态)JavaScript库 为了让开发轻松点, 使用一个JavaScript接口来和数据库交互是个好主意, 它在QML中提供了方便的方法; 在QtCreator中 ...
- 微信小程序开发之入门篇(熟悉项目结构)
微信小程序创建之后会生成一个项目模板,如下图所示(基本如此,但并不局限于此) 现在分别来说明一下每个文件及目录的意思 app.js 程序的入口文件,必须存在. app.js是小程序的脚本代码.我们可以 ...
随机推荐
- 简单的积雪shader
// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject' Shader "Custom/CoverSnow&q ...
- 批处理--md5校检
@echo off rem 获取文件xx.zip的MD5 for /f "delims=" %%i in ('md5.exe xx.zip') do (set md5_var=%% ...
- window下安装php7的memcache扩展
安装memcache:http://www.runoob.com/memcached/memcached-connection.html1.4.4 c:\memcached\memcached.exe ...
- random随机模块,time时间模块
random /随机模块: 作用: 在某个范围内取到每一个值得概率是相通的. 一.随机小数 random.random() import random print(random.random()) ...
- C# RangeHelper
/// <summary> /// Range Helper /// </summary> /// <typeparam name="T">&l ...
- Python的自省机制
什么是自省? 在日常生活中,自省(introspection)是一种自我检查行为. 在计算机编程中,自省是指这种能力:检查某些事物以确定它是什么.它知道什么以及它能做什么.自省向程序员提供了极大的灵活 ...
- Linux c编程:同步属性
就像线程具有属性一样,线程的同步对象(如互斥量.读写锁.条件变量.自旋锁和屏障)也有属性 1.互斥量属性 用pthread_mutexattr_init初始化pthread_mutexattr_t结构 ...
- xcode6
官方的xcode6下载太慢,这里送上百度网盘地址: http://pan.baidu.com/s/1hqze1hi
- Struts2之ModelDriven的使用
http://www.cnblogs.com/luoyanli/archive/2012/11/20/2778361.html 我们可以根据Action属性的不同将它分为两类:Field-Driven ...
- 【转载】Java定时器的学习
前几看了一下<thinking in java>了解到java原生的Times类有两个问题: (1)Timer是启动单个线程来处理所有的时间任务,如果一个任务耗时很久,那么如果在执行这个过 ...