转自:http://blog.csdn.net/anders_zhuo/article/details/9444145
1.The Basics
'context' 是Velocity 中的一个核心概念, 这是一个从系统的”数据容器(a container of data)”引出的一个常见概念. 这里的context 在java 程序层和模板视图层(template layer ( or the designer))之间扮演着一个”数据对象传送者”'(carrier')的角色.
做为程序员,你可以将你程序生成的不同类型的数据对象放入context 中,对于视图设计来说,这些对象(包含它们的数据域和命令)将在模板元素中被引用到(references)。一般来说,你将和视图设计者一起决定应用需要哪些数据,可以说,你放入context 中的数据对象在这里成为一种”API”,由视图设计者在模板中来访问.因此,在向context 中决定放放哪些数据对象时,程序的设计者需要仔细分析视图表现所需的数据内容。
虽然Velocity 中你可以创建自己的Context 类来支持一些个性化的应用(比如,一个访问,保存LDAPServer 服务的context),你可以实现VelocityContext 这个己封装较为完务的基类。VelocityContext 对象基本上可满足大多的应用, 我们强烈建议你除非在特别的情况下,否则不要创建自己的Context 实现!
VelocityContext 用法十分简单,类似于Hashtable class.下面是这个接口提供的两个基本用法:
public Object put(String key, Object value);
public Object get(String key);
很像Hashtable 吧,这里的value 必须是一个java.lang.Object类(不能是原始类型,像int,boolean), 也不能是null 值. 原始类型(Fundamental types like int or float)必须被包装为一个适当对应的Object 型.
2.在模板中用#foreach 指令支持迭代对象
在放入context 前,你对对象有着全面的操作自由. 但就像所有的自由一样, 你必须遵守一些规则,承担一些责任,因此,你必须理解Velocity 是如何使用对象的,Velocity 的VTL 支持多种类型的集合类型(collection types) 使用#foreach().
Object [] 一般对象数组. Velocity 将内功能会将它包装成功之为一个实现Iterator interface 对象, 这个转换是不需要程序员或视图设计者参与.
java.util.Collection :Velocity 会使用他们的标准iterator() 得到一个可以迭代中使用的Iterator 对象,如果你使用自己的实现了Collection interface 的对象,要确保它的iterator()命令返回一个可用的Iterator.
java.util.Map 接口对象,Velocity 使用其顶层接口的values() 命令得到一个实现Collectioninterface 的对象, 应用其iterator()再返回一个Iterator.
java.util.Iterator 使用特别注意: 如果一个Iterator 对象被放置到context 中,当在模板中有多个#foreach()指令中,这些#foreach() 将顺序执行,如果第一个调用失败,后面的将阻塞且不能重置.
java.util.Enumeration USE WITH CAUTION : 如同java.util.Iterator 一样的道理,Velocity将使用的是一个不能重置('non-resettablity')或者说一个final 型的对象.因此,仅当在不得己的情况下,Iterator and Enumeration 对象才有必要放入context 中---也许你有更好的办法不使用他们.
例子1:
vm文件内容:
java代码:
输出文件内容:
hello word 世界 Shanghai Beijing
3.Context Chaining
另外一个新引入的概念是context chaining.有时也叫做context wrapping(有点类似与servlet 中的chain), 这个高级特性让你可以连结多个独立的Velocity 的contexts,以便在template 中使用.
vm文件内容:
hello $name $city
java代码:
可以看到
4.模板中的己创建对象
Java 代码中的数据对象与模板交互有两种常见方式:
模板设计者从模板中执行程序员放入到context 中的java 对象的命令:
#set($myarr = ["a","b","c"] )
$foo.bar( $myarr )
当模板加入一个对象到context 中,模板合并输出后,java 代码将可以访问这些对象.
#set($myarr = ["a","b","c"] )
#set( $foo = 1 )
#set( $bar = "bar")
5.Context 对象的其它用法
每一个VelocityContext(或任意源自AbstractContext)的对象,都是一个封装好指定规则的的存储节
点,对于一般开发都来说,只需使用就是.但这里还有一些你应知道的特性:
考虑以下情况:
你的模板重复使用VelocityContext object.
Template caching is off.
反复调用getTemplate() 命令.
这都有可能引起VelocityContext 的内存泄露( 'leak' memory )---当它汇集过多的数据对象时,因此
强烈建议你做到以下几点:
在每个模板渲染过种中(template render process)创建一个新的VelocityContext. 这会防止
过多的cache data. 当需要重用一个VelocityContext 因为它内部己放置了数据对象, 你只需
要像这样简单的包装一下:VelocityContext useThis = new VelocityContext( populatedVC );
具体可以参看Context chaining 获取更多信息.
打开模板的caching 功能. 以防止重复解析模板,当然,这会要求服务器有更高的性能.
在迭代操作时,要重用模板对象. 这样将不会对Velocity 造成过大压力, 如果缓存关闭, 就需要每次都
读取和解析模板, 导致VelocityContext 中每次都要保存大量新的信息.
本文由 SAn 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为:
2018/01/26 15:31