Basics
您已经了解了如何使用标准 Java 类(Map
,String
等)在Getting Started中构建数据模型。在内部,模板中可用的变量是实现freemarker.template.TemplateModel
接口的 Java 对象。但是您可以将标准 Java 集合用作数据模型中的变量,因为这些变量已被幕后的TemplateModel
实例替换。此功能称为 对象包装 。对象包装工具可以将任何类型的对象透明地转换为实现TemplateModel
接口的类的实例。例如,这使得可以将java.sql.ResultSet
作为模板中的序列变量进行访问,或者将javax.servlet.ServletRequest
对象作为包含请求属性的哈希变量进行访问,甚至可以将 XML 文档作为 FTL 变量(see here)进行遍历。但是,要包装(转换)这些对象,您需要插入正确的ObjectWrapper
实现(可能是您的自定义实现); later对此进行讨论。现在的要点是,迟早要从模板访问的任何对象都必须转换为实现TemplateModel
接口的对象。因此,首先您应该熟悉TemplateModel
实现的编写。
大约有一个freemarker.template.TemplateModel
子代接口,对应于变量的每种基本类型(TemplateHashModel
表示散列,TemplateSequenceModel
序列,TemplateNumberModel
表示数字等)。例如,如果要公开java.sql.ResultSet
作为模板的序列,则必须编写一个可以读取java.sql.ResultSet
-s 的TemplateSequenceModel
实现。我们曾经说过,您将java.sql.ResultSet
与TemplateModel
实现一起包装,因为基本上您只是封装了java.sql.ResultSet
以便通过通用的TemplateSequenceModel
接口提供对其的访问。注意,一个类可以实现多个TemplateModel
接口。这就是为什么 FTL 变量可以具有多种类型的原因(请参阅:模板作者指南/值,类型/基础)
请注意,freemarker.template
软件包提供了这些接口的简单实现。例如,要将String
转换为 FTL 字符串变量,可以使用SimpleScalar
,将java.util.Map
转换为 FTL 哈希变量,可以使用SimpleHash
等。
尝试自己的TemplateModel
实现的一种简单方法是创建该实例的实例,然后将其直接放入数据模型中(例如put
放入根哈希中)。由于对象包装器已经实现了TemplateModel
,因此对象包装器将不加修饰地将其暴露给模板,因此无需进行任何转换(包装)。 (在您不希望对象包装器尝试包装(转换)某个对象的情况下,此技巧也很有用。)