资源管理器必须实现 org.apache.velocity.runtime.resource.ResourceManager interface. 具体描述请看api文档. 尽量使用默认实现,除非你认为有必要在以下参数中换成你自己的 :
resource.manager.class
这个参数也可通过RuntimeConstants.RESOURCE_MANAGER_CLASS 设定。
资源的caching必须实现 org.apache.velocity.runtime.resource.ResourceCache interface 接口,配置到参数中是 :
resource.manager.cache.class
这个参数也可通过 RuntimeConstants.RESOURCE_MANAGER_CACHE_CLASS 设定
13.Template Encoding for Internationalization(字符编码和国际化)
从版本1.1开始, 可以设定资源的编解码类型. 在API中也可以传入解码的方式 :
org.apache.velocity.servlet.VelocityServlet :
public Template getTemplate( String template, String encoding )
org.apache.velocity.app.Velocity :
public static Template getTemplate(String name, String encoding) public static boolean mergeTemplate( String templateName, String encoding, Context context, Writer writer )
encoding 参数可以设定为JVM支持的某个值 "UTF-8" or "ISO-8859-1".关于字符集正式的名字, see here.
注意,这仅仅是编码了模板自己 – 输出的编码由应用程序指定.
14.Velocity and XML
Velocity's的VTL( velocity template language)处理XML数据很方便. Anakia是一个用XSL从XML中输出视图的例子. Velocity站点,文档包括 Jakarta site is also rendered using Anakia.
一般来说,处理XML会用到 JDOM 这样的东东将XML转成java数据结构 ,如下例示是一个XML文档 :
< xml version="1.0" >
一小段处理的读取XML的java程序如下:
...
SAXBuilder builder;
Document root = null;
try
{
builder = new SAXBuilder( "org.apache.xerces.parsers.SAXParser" );
root = builder.build("test.xml");
}
catch( Exception ee)
{}
VelocityContext vc = new VelocityContext();
vc.put("root", root );
...
(See the Anakia source for details on how to do this, or the Anakia example in the examples directory in the distribution.) 现在,在模板中应用 :
The document title is
$root.getChild("document").getChild("properties").getChild("title").getText()
就像渲染一般模板那样, 使用 Context 中的JDOM tree. 虽然这个例子看起来不漂亮, 但它展示了这样做是多么容易.
One real advantage of styling XML data in Velocity is that you have access to any other object or data that the application provides. You aren't limited to just using the data present in the XML document. You may add anything you want to the context to provide additional information for your output, or provide tools to help make working with the XML data easier. Bob McWhirter's Werken Xpath is one such useful tool - an example of how it is used in Anakia can be found in org.apache.velocity.anakia.XPathTool.
One issue that arises with XML and Velocity is how to deal with XML entities. One technique is to combine the use of Velocimacros when you need to render an entity into the output stream :
## first, define the Velocimacro somewhere
#macro( xenc $sometext )$tools.escapeEntities($sometext)#end
## and use it as
#set( $sometext = " < " )
where the escapeEntities() is a method that does the escaping for you. Another trick would be to create an encoding utility that takes the context as a constructor parameter and only implements a method:
public String get(String key)
{
return (obj != null) Escape.getText( obj.toString() ) : "";
}
Put it into the context as "xenc". Then you can use it as :
This takes advantage of Velocity's introspection process - it will try to call get("sometext") on the $xenc object in the Context - then the xenc object can then get the value from the Context, encode it, and return it.
Alternatively, since Velocity makes it easy to implement custom Context objects, you could implement your own context which always applies the encoding to any string returned. Be careful to avoid rendering the output of method calls directly, as they could return objects or strings (which might need encoding). Place them first into the context with a #set() directive and the use that, for example :
#set( $sometext = $jdomElement.getText() )
The previous suggestions for dealing with XML entities came from Christoph Reck, an active participant in the Velocity community. We are very grateful for his [unknowing] contribution to this document, and hope his ideas weren't mangled too badly :)
15.FAQ (Frequently Asked Questions)
开发中常见的问题解答.
1.Why Can't I Access Class Members and Constants from VTL
在VTL中无法访问到类的数据域
最简单的原因是我们无法反射/内省(introspect )这个对象.因为就OOP来说,对象中要隐藏自己没有必要外露的数据或命令.解决方法:包状成publicly 命令反回它,保证它是公开访问的. 当然,你要保证能改动源文件, 否则,就要用工具来解析它. org.apache.velocity.app.FieldMethodizer是用来解析你的类的, 如下示例如何将一个public static fields 导出到模板中.假设你的类是 :
public class Foo
{
public static String PATH_ROOT = "/foo/bar";
....
}
你可这样将它放入context中:
context.put("myfoo", new FieldMethodizer( new Foo() ) );
然后在模板中就可以java代码的风格来访问 :
$myfoo.PATH_ROOT
如果你需要访问public的非静态域时(public non-static members)甚止是私有成员!那你就必须扩展或重写 FieldMethodizer 这个类----但你为什么要搞得这么复杂呢?
2.Where does Velocity look for Templates
Velocity到哪里提取模板文件?
默认的,不做任何配置更改的情况下,Velocity会在当前目录下或相对与当前目录(如'foo/bar.vm')下查找.
Velocity对这些都是自动处理的. Velocity只记住它自己的一个root目录,这个概念不同与多根目录的文件系统(like - "C:\", "D:\", etc).
16.Summary
希望这个指南能帮助您出色的将velocity应用到项目中. 请将您的意见反馈发送到mail lists.
17.Appendix 1 : Deploying the Example Servlet
布署本文中的Servlet例程
Servlet开发者经常受到的一个打击是将servlet放错了地方---一切都是好的除此之外. 使用Tomcat 、 Resin i这样的Servlet容器都可以运行起我们的SampleServlet . SampleServlet.java 在目录 examples/servlet_example 下. 虽然有些servlet engines (Resin, for example) 会自动将它编译,但是为了学习,还是你亲自动手先将它编译过.
Jakarta Tomcat
Jakarta Tomcat 的安装就不多说了. 'webapp' 目录是tomcat默认的查找它的web应用的root.所以,以下是我们要做的:
首先,创建一个新的 'webapp' 暂时名叫 velexample 放到Tomcat的webapps 目录下, 这个新的目录结构如下 :
velexample velexample/WEB-INF velexample/WEB-INF/lib velexample/WEB-INF/classes
将Velocity jar 放到velexample/WEB-INF/lib下. (从1.2版本后,所有相关依赖包都打包在. velocity-dep-1.2.jar中),当然,相关的依赖包也必须放到WEB-INF/lib下. 具体可以看 "Getting Started" and "Dependencies", 这两节的介绍.
将编译过的SampleServlet.class放到 velexample/WEB-INF/classes 下.
将sample.vm 放到目录velexample 下.
现在就可以启动servlet来访问servlet了.
在Browser中输出如下 :
Caucho Technology's Resin
Setting up the example servlet under Caucho Technology's Resin servlet engine is also very simple. The following instructions were tested with the version 1.2.5 release. The following assume that you have unzip-ed or untar-ed the distribution, know how to start the servlet engine (something like bin/httpd.sh under unix...), and know where the doc directory is (in the root of the distribution).
Copy the SampleServlet.class file into the doc/WEB-INF/classes directory.
Copy the sample.vm template file into the doc/ directory
Copy the Velocity jar (and any required dependencies - see note above in Tomcat setup section) into the doc/WEB-INF/lib directory.
Start resin.
To access the servlet, point your web browser at :
http://localhost:8080/servlet/SampleServlet
or if that doesn't work :
http://
and you should see the output.
Note that this appeared to be a simpler configuration - with the Tomcat example, you set up a complete, new, separate webapp, whereas the Resin instructions don't, although both should provide a sufficient setup to let you play with Velocity.
Note that while we wish we could, we can't answer questions about the servlet engines. Please use the resources provided by the servlet engine provider.
BEA WebLogic
Paw Dybdahl