《Velocityjava开发指南》中文版.docx
《《Velocityjava开发指南》中文版.docx》由会员分享,可在线阅读,更多相关《《Velocityjava开发指南》中文版.docx(47页珍藏版)》请在冰点文库上搜索。
![《Velocityjava开发指南》中文版.docx](https://file1.bingdoc.com/fileroot1/2023-7/8/886bb20e-2418-450d-a06b-4d8e65989fea/886bb20e-2418-450d-a06b-4d8e65989fea1.gif)
《Velocityjava开发指南》中文版
《Velocityjava开发指南》中文版
本文档来自网络,本人将其收集整理了一下,主要调整了一下格式.如有出入,请参照网络原版,原版地址记不清了!
O(∩_∩)O哈哈~
目录
开始入门3
参考资源:
4
它是如何工作的?
5
单实例还是多实例(ToSingletonOrNotToSingleton...)?
7
TheContext9
UsingVelocityInServlets12
UsingVelocityInGeneralApplications15
ApplicationAttributes19
EventCartridgeandEventHandlers(事件分发和处理)20
VelocityConfigurationKeysandValues(配置参数名字和值说明)23
ConfiguringtheLogSystem(日志记录配置)26
ConfiguringResourceLoaders(资源装载器配置)29
TemplateEncodingforInternationalization(字符编码和国际化)32
VelocityandXML33
FAQ(FrequentlyAskedQuestions)开发中常见的问题解答.36
Summary37
Appendix1:
DeployingtheExampleServlet38
开始入门
Velocity是一基于java语言的模板引擎,使用这个简单、功能强大的开发工具,可以很容易的将数据对象灵活的与格式化文档组装到一起;希望本文能指引使用velocity在开发基于servlet或一般java应用程序的应用上快速起步。
1.GettingStarted
取得Velocity并在你的机器上开始运行很容易,以下是全部详细的说明:
取得Velocity发布版本,gohere。
目录及文件说明:
Velocity-X.jar完整的velocityjar包一般命名格式为velocity-X.jar,其中X是当前版本号。
注意这个jar包不包含Velocity所必须依赖的其它jar包(具体见后)。
SRC:
完整的源文件代码目录
Examples.完整的aplication或webApp例子。
docs:
Veocity文档目录
build:
使用ant编译源码时所需的lib.
OK,现在就可以开始使用了.请将Velocity-x.jar放到你的classpath中或webapp的lib下。
当然,我们强烈建议你先运行其中的例子,以感受Velocity的优异之处.
2.Dependencies依赖资源
Velocity可运行于JDK1.4或JRE1.4及其以上版本.
Velocity也依赖于其它一些jar包,在分发版本的build/lib有,如果你下载的是二进制分发版本,需要到以下地址下载其它依赖包.
JakartaCommonsCollections–必须.
JakartaAvalonLogkit–可选,但强列建议加上,以便输出日志信息.
JakartaORO–可选,仅当用到org.apache.velocity.convert.WebMacrotemplate这个模板转换工具时.
参考资源:
一些优秀的资源和例程列表如下:
开发者邮件列表mail-lists.
邮件档案表:
http:
//www.mail-是很好的一个资源库.可以以’Velocity’为关键字进行搜索。
源代码(源码分发版本):
src/java/...:
含有Velocityproject的所有源码
应用程序例程1:
examples/app_example1:
一个很简单的示例如何在一般应用程序中使用Velocity.
应用程序例程12:
examples/app_example2:
如何在应用程序中使用Velocity工具类.
servletexample:
examples/servlet_example1:
示例如何在servlet中用Velocity输出模板.
loggerexample:
examples/logger_example:
如何定制Velocity的日志工具.
XMLexample:
examples/xmlapp_example:
使用JDOM从Velocity模板读取内容.还包含一个递归调用宏的示例.
eventexample:
examples/event_example:
在Velocity1.1中使用事件处理API。
Anakiaapplication:
examples/anakia:
示例用stylesheet美化xml数据。
Forumdemowebapp:
examples/forumdemo:
一个基于servlet的论坛功能实现示例.
templates:
test/templates:
全面展示VTL(VelocityTemplateLanauage)功能的模板集合。
contextexample:
examples/context_example:
两个示例如何重写(继承)Velocitycontext功能的例子(针对高级用户).
它是如何工作的?
3.基本使用模式
在applicationprogram或servlet中使用Velocity中,一般通过如下步骤:
对于所有应用,第一步是要初始化Velocity,一般使用唯一实例模式(Singleton),如Velocity.init().
创建一个Contextobject.
将你的数据对象加入到Context对象中.
使用Velocity选择一个模板.
合并模板和数据导出到输出流.
下面的代码,通过使用org.apache.velocity.app.Velocity的单实例模式,合并输出:
Java代码
1importjava.io.StringWriter;
2importorg.apache.velocity.VelocityContext;
3importorg.apache.velocity.Template;
4importorg.apache.velocity.app.Velocity;
5importorg.apache.velocity.exception.ResourceNotFoundException;
6importorg.apache.velocity.exception.ParseErrorException;
7importorg.apache.velocity.exception.MethodInvocationException;
8
9//初始化
10Velocity.init();
11//取得VelocityContext对象
12VelocityContextcontext=newVelocityContext();
13//向context中放入要在模板中用到的数据对象
14context.put("name",newString("Velocity"));
15Templatetemplate=null;
16//选择要用到的模板
17try
18{
19template=Velocity.getTemplate("mytemplate.vm");
20}
21catch(ResourceNotFoundExceptionrnfe)
22{
23//couldn'tfindthetemplate
24}
25catch(ParseErrorExceptionpee)
26{
27//syntaxerror:
problemparsingthetemplate
28}
29catch(MethodInvocationExceptionmie)
30{
31//somethinginvokedinthetemplate
32//threwanexception
33}
34catch(Exceptione)
35{}
36
37StringWritersw=newStringWriter();
38//合并输出
39template.merge(context,sw);
以上是基本的使用模式,看起来非常简洁!
这些都是一般情况下使用Velocity所必须的步骤.但你可能不想这样按部就班的编写代码–Velocity提供了一些工具以更容易的方式在servlet或应用程序中使用。
在这个指南的后面,我们将讨论在servlet和普通应用程序中更好的用法.
单实例还是多实例(ToSingletonOrNotToSingleton...)?
4.SingletonModel
这是系统默认的模式,这样在jvm(应用程序)或webaplication(一个web程序)中只存在一个Velocityengine实例共享使用。
.这对于配置和共享资源来说非常方便.比如,这非常适合用于支持Servlet2.2+的webapplication中,每一个webapp持有它自己的唯一Velocity实例,它们可以共享templates,alogger等资源.Singleton可以直接通过使用org.apache.velocity.app.Velocity类,如下例子:
Java代码
40importorg.apache.velocity.app.Velocity;
41importorg.apache.velocity.Template;
42
43/*
44*Configuretheengine-asanexample,weareusing
45*ourselvesasthelogger-seeloggingexamples
46*/
47
48Velocity.setProperty(Velocity.RUNTIME_LOG_LOGSYSTEM,this);
49
50/*
51*nowinitializetheengine
52*/
53
54Velocity.init();
55
56Templatet=Velocity.getTemplate("foo.vm");
5.SeparateInstance
在1.2版本以后,可以在JVM(orwebapplication.)创建,配置,使用多个Velocity实例;当你希望在同一程序中,对每个实例独立配置时它们的templatedirectories,loggers等资源时,这是非常方便的.多实例化时,我们要用到org.apache.velocity.app.VelocityEngine类.下面是一个例子,请注意和上面singletonexample同法时的不同:
Java代码
57importorg.apache.velocity.app.VelocityEngine;
58importorg.apache.velocity.Template;
59
60...
61
62/*
63*createanewinstanceoftheengine
64*/
65
66VelocityEngineve=newVelocityEngine();
67
68/*
69*configuretheengine.Inthiscase,weareusing
70*ourselvesasalogger(seeloggingexamples..)
71*/
72
73ve.setProperty(VelocityEngine.RUNTIME_LOG_LOGSYSTEM,this);
74
75/*
76*initializetheengine
77*/
78
79ve.init();
80
81...
82
83Templatet=ve.getTemplate("foo.vm");
可以看到,这是非常简单的直接使用就行了.无论用singleton或separateinstances都不需要改变你程序的上层结构及模板内容.
对于开发人员而言,你应在以下两个类中二者择一的使用
org.apache.velocity.app.Velocity应用于singletonmodel,org.apache.velocity.app.VelocityEngine一般用于non-singletonmodel('separateinstance').
TheContext
6.TheBasics
'context'是Velocity中的一个核心概念,这是一个从系统的”数据容器(acontainerofdata)”引出的一个常见概念.这里的context在java程序层和模板视图层(templatelayer(orthedesigner))之间扮演着一个”数据对象传送者”'(carrier')的角色.
做为程序员,你可以将你程序生成的不同类型的数据对象放入context中,对于视图设计来说,这些对象(包含它们的数据域和命令)将在模板元素中被引用到(references)。
一般来说,你将和视图设计者一起决定应用需要哪些数据,可以说,你放入context中的数据对象在这里成为一种”API”,由视图设计者在模板中来访问.因此,在向context中决定放放哪些数据对象时,程序的设计者需要仔细分析视图表现所需的数据内容。
虽然Velocity中你可以创建自己的Context类来支持一些个性化的应用(比如,一个访问,保存LDAPServer服务的context),你可以实现VelocityContext这个己封装较为完务的基类。
VelocityContext对象基本上可满足大多的应用,我们强烈建议你除非在特别的情况下,否则不要创建自己的Context实现!
VelocityContext用法十分简单,类似于Hashtableclass.下面是这个接口提供的两个基本用法:
publicObjectput(Stringkey,Objectvalue);
publicObjectget(Stringkey);
很像Hashtable吧,这里的value必须是一个java.lang.Object类(不能是原始类型,像int,boolean),也不能是null值.原始类型(Fundamentaltypeslikeintorfloat)必须被包装为一个适当对应的Object型.
OK,以上就是context对象的用法概念,很简单我们却哆嗦这么:
).关于其更多的介绍,请见APIdocumentation.
7.在模板中用#foreach指令支持迭代对象
在放入context前,你对对象有着全面的操作自由.但就像所有的自由一样,你必须遵守一些规则,承担一些责任,因此,你必须理解Velocity是如何使用对象的,Velocity的VTL支持多种类型的集合类型(collectiontypes)使用#foreach().
Object[]一般对象数组.Velocity将内功能会将它包装成功之为一个实现Iteratorinterface对象,这个转换是不需要程序员或视图设计者参与.
java.util.Collection:
Velocity会使用他们的标准iterator()得到一个可以迭代中使用的Iterator对象,如果你使用自己的实现了Collectioninterface的对象,要确保它的iterator()命令返回一个可用的Iterator.
java.util.Map接口对象,Velocity使用其顶层接口的values()命令得到一个实现Collectioninterface的对象,应用其iterator()再返回一个Iterator.
java.util.Iterator使用特别注意:
如果一个Iterator对象被放置到context中,当在模板中有多个#foreach()指令中,这些#foreach()将顺序执行,如果第一个调用失败,后面的将阻塞且不能重置.
java.util.EnumerationUSEWITHCAUTION:
如同java.util.Iterator一样的道理,Velocity将使用的是一个不能重置('non-resettablity')或者说一个final型的对象.
因此,仅当在不得己的情况下,IteratorandEnumeration对象才有必要放入context中---也许你有更好的办法不使用他们.
例如,你可以将如下代码:
Vectorv=newVector();
v.addElement("Hello");
v.addElement("There");
context.put("words",v.iterator());
替换为:
context.put("words",v);
8.ContextChaining
另外一个新引入的概念是contextchaining.有时也叫做contextwrapping(有点类似与servlet中的chain),这个高级特性让你可以连结多个独立的Velocity的contexts,以便在template中使用.
以下是这种用法的代码示例:
Java代码
84VelocityContextcontext1=newVelocityContext();
85
86context1.put("name","Velocity");
87context1.put("project","Jakarta");
88context1.put("duplicate","Iamincontext1");
89
90VelocityContextcontext2=newVelocityContext(context1);
91
92context2.put("lang","Java");
93context2.put("duplicate","Iamincontext2");
94
95template.merge(context2,writer);
在上面的代码中,context2做为context1的chains.这意味着你在模板中可以使用放入这两个context中的任何一个对象,当两个context中有相同的key中,在模板中输出时,将会输出最后一个key的值,如上例key为duplicate的值将输出为"Iamincontext2".
其实,在上例中不存在duplication,或'covering',context1中的string"Iamincontext1"依然可以通过context1.get("duplicate")方法得到.但在上例中,模板中引用'$duplicate'将会返回'Iamincontext2',而且模板不能再访问到context1中的'Iamincontext1'.
另外要注意的是,当你尝试在模板中加入信息,比如使用#set()声明,这将对所己输出的模板产生影响.
如前所述,Velocitycontext类也是或扩展的,但在这份指南中没有述及.如果你有兴趣,可以查看org.apache.velocity.context中的代码以了解contexts是如何生成,java数据对象以何机制传出的.例程examples/context_example有一些示例展现.
9.模板中的己创建对象
Java代码中的数据对象与模板交互有两种常见方式:
模板设计者从模板中执行程序员放入到context中的java对象的命令:
#set($myarr=["a","b","c"])
$foo.bar($myarr)
当模板加入一个对象到context中,模板合并输出后,java代码将可以访问这些对象.
#set($myarr=["a","b","c"])
#set($foo=1)
#set($bar="bar")
这里述及这些技巧有些过早,但现在必须理解以下概念:
TheVTL通过context或method所传的[1..10]andObjectArray["a","b"]是java.util.ArrayList对象.因此你的对象的命令设计时,要具有兼容性.
Numbers在context中将被包装为Integers,strings,当然就是Strings了.
Velocity会适当的根据调用的参数类型适配对象的调用命令,setFoo(inti)将一个int放入context和#set()是不会冲突的.
10.Context对象的其它用法
每一个VelocityContext(或任意源自AbstractContext)的对象,都是一个封装好指定规则的的存储节点,对于一般开发都来说,只需使用就是.但这里还有一些你应知道的特性:
考虑以下情况:
你的模板重复使用VelocityContextobject.
Templatecachingisoff.
反复调用getTemplate()命令.
这都有可能引起VelocityContext的内存泄露('leak'memory)---当它汇集过多的数据对象时,因此强烈建议你做到以下几点:
在每个模板渲染过种中(templaterenderprocess)创建一个新的VelocityContext.这会防止过多的cachedata.当需要重用一个VelocityContext因为它内部己放置了数据对象,你只需要像这样简单的包装一下:
VelocityContextuseThis=newVelocityContext(populatedVC);具体可以参看Contextchaining获取更多信息.
打开模板的caching功能.以防止重复解析模板,当然,这会要求服务器有更高的性能.
在迭代操作时,要重用模板对象.这样将不会对Velocity造成过大压力,如果缓存关闭,就需要每次都读取和解析模板,导致VelocityContext中每次都要保存大量新的信息.
UsingV