<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    JAVA流通橋

    JAVA啟發(fā)者

    統(tǒng)計

    留言簿(3)

    AJAX相關(guān)網(wǎng)址

    Eclipse相關(guān)網(wǎng)址

    Hibernate

    java相關(guān)網(wǎng)址

    LINUX相關(guān)網(wǎng)址

    webwork相關(guān)網(wǎng)址

    友好鏈接

    閱讀排行榜

    評論排行榜

    Velocity開發(fā)者指南

    1. 概述和入門Introduction and Getting Started
    2. 資源Resources
    3. Velocity怎樣工作How Velocity Works
      • 基本的格式The Fundamental Pattern
    4. 使用Singleton還是不使用To Singleton Or Not To Singleton...
      • Singleton模式Singleton Model
      • Separate Instance
    5. 上下文The Context
      • 基礎(chǔ)原則The Basics
      • 對使用#foreach()遍歷對象的支持Support for Iterative Objects for #foreach()
      • 上下文鏈Context Chaining
      • 模版創(chuàng)建的對象Objects Created by the Template
      • 其他問題Other Context Issues
    6. 在Servlets里使用VelocityUsing Velocity in Servlets
      • Servlet編程Servlet Programming
      • 部署Deployment
    7. 在一般的應(yīng)用中使用VelocityUsing Velocity in General Applications
      • Velocity Helper對象The Velocity Helper Class
      • 異常Exceptions
      • 更多的細節(jié)Miscellaneous Details
    8. 應(yīng)用的屬性Application Attributes
    9. EventCartridge 和 Event Handlers
    10. Velocity的配置Velocity Configuration Keys and Values
    11. 配置日志系統(tǒng)Configuring the Log System
      • 使用現(xiàn)有的Log4jUsing Log4j With Existing Category
      • 一個自定義日志的例子Simple Example of a Custom Logger
    12. 配置資源加載器(模版加載器)Configuring the Resource Loaders (template loaders)
      • 資源加載器Resource Loaders
      • 配置示例Configuration Examples
      • 插拔式的資源管理器和資源緩存Pluggable Resource Manager and Resource Cache
    13. 模版的編碼和國際化Template Encoding for Internationalization
    14. Velocity 和 XML
    15. FAQ (Frequently Asked Questions)
    16. 總結(jié)Summary
    17. 附錄1:部署示例ServletAppendix 1 : Deploying the Example Servlet
      • Jakarta Tomcat
      • Caucho Technology's Resin
      • BEA

    概述

    Velocity是一個基于Java技術(shù)的模版引擎,是一個簡單但強大的使你能輕松的創(chuàng)建和合成具有一定格式,用于展現(xiàn)數(shù)據(jù)的文檔的工具。在本指南中,我們希望能使你對使用Velocity能有一個比較全面的認識。主要關(guān)注兩個主要的使用Velocity的領(lǐng)域:Velocity is a Java-based template engine, a simple and powerful development tool that allows you to easily create and render documents that format and present your data. In this guide, we hope to give an overview of the basics of development using Velocity, focusing on the two main areas for Velocity usage :

    • 基于servlet的web應(yīng)用。servlet-based WWW development
    • 普通的應(yīng)用。general application use

    你將會發(fā)現(xiàn)其實兩者之間的差別很小。當(dāng)使用我們提供的VelocityServlet作為基于servlet的web應(yīng)用的基礎(chǔ),加上我們提供的一些工具類,構(gòu)建一個web應(yīng)用會及其的簡單。You will see that there is no real difference between these, other than we make servlet development with Velocity very easy if you use our provided class VelocityServlet as a base class for your servlet, and offer a utility class to help with application development.

    入門Getting Started

    即使在Velocity官方網(wǎng)站還是在Velocity的文檔中,都能找到下面的信息,但是為了完整這里還是再提下。要使Velocity在你的電腦上開始工作是很簡單的事情。注意下面提到的文件夾都是從你的Velocity發(fā)布文件的根目錄開始的。While this information is found elsewhere on the Velocity site and in the documentation, it is included here for completeness. Getting Velocity running on your computer is very easy. Note that all directory references are relative the root of the Velocity distribution tree.

    1. 得到Velocity的發(fā)布文件。Get the Velocity distribution. This is available as a release, nightly snapshot or directly from the CVS code repository. Any are fine, although for the latest features, the nightly snapshot is most likely the best way. For more information, go here.
    2. 如果你還沒有安裝Jakarta Ant這個構(gòu)建工具,請安裝好它。需要Ant是為了構(gòu)建Velocity,而不是為了使用Velocity。If you don't have Jakarta Ant, the Java build tool already installed, please do so. It is required for building Velocity, although not required for using Velocity.
    3. 切換到發(fā)布文件的build文件夾下。Go to the build directory in the distribution.
    4. 輸入 ant <build target>,其中,<build target>將會是下面之一:Type ant <build target> where <build target> is one of:
      • jar 在bin文件夾下構(gòu)建完整的Velocity jar文件。這個jar文件會命名為Velocity-X.jar,其中X是當(dāng)前Velocity的版本號。注意這個jar文件沒有包括Velocity必需的庫文件。如果你使用了這個任務(wù),你需要從JAakarta Commons上得到Collections組件,并且將該jar文件添加到你的CLASSPATH中(或者放到WEB-INF/lib)。如果你希望使用日志或其他功能,你也需要把相關(guān)的jar文件添加到CLASSPATH或者WEB-INF/lib中。為了方便,你可以直接使用jar-dep任務(wù)來將需要的jar都打包到一起。builds the complete Velocity jar in the bin directory. This jar will be called 'velocity-X.jar', where 'X' is the current version number. This jar does not include necessary dependencies for Velocity. If you use this target, you must get the Collections component jar from Jakarta Commons and add to your CLASSPATH (or WEB-INF/lib). If you wish to use the built-in logging or template conversion, you must include the appropriate jars in your CLASSPATH or webapp's WEB-INF/lib. For convenience, you can use the jar-dep target to build a jar with ORO, Logkit and Commons Collections included.
      • jar-dep 在bin文件夾下構(gòu)建完整的Velocity jar文件,包括了Velocity所有依賴的庫文件。builds the complete Velocity jar in the bin directory, including necessary support for logging from the Jakarta Avalon Logkit package, critical configuration support from the Jakarta Commons and the necesary support for WebMacro template conversion using the Jakarta ORO package.
      • jar-core 在bin文件夾下構(gòu)建一個小型的Velocity jar文件,該文件叫做velocity-core-X.jar。該jar中只包括了Velocity最核心的功能,不包括例子和工具,比如Anakia,Texen,VelocityServlet等。關(guān)于該jar文件的依賴組件和jar任務(wù)一樣,也沒有包括。builds a slimmer Velocity jar in the bin directory, called 'velocity-core-X.jar'. This jar contains the core Velocity functionality, and doesn't include example and utility things like Anakia, Texen or the VelocityServlet support baseclass. It has the same external dependency requirements as the regular jar target.
      • jar-util 在bin文件夾中構(gòu)建Velocity的工具jar,該文件叫做velocity-util-X.jar。該jar中只包含了Velocity提供的工具,Anakia,Texen和WebMacro模版轉(zhuǎn)換工具。關(guān)于該jar文件的依賴組件和jar任務(wù)一樣,也沒有包括。builds a utility Velocity jar in the bin directory, called 'velocity-util-X.jar'. This jar contains utility code, specifically Anakia, Texen, and the WebMacro template conversion utility. It has the same external dependency requirements as the regular jar target.
      • jar-servlet 在bin文件夾中構(gòu)建Velocity的工具jia,該文件叫做velocity-servlet-X.jar。該jar包含了servlet相關(guān)的工具代碼。關(guān)于該jar文件的依賴組件和jar任務(wù)一樣,也沒有包括。builds a utility Velocity jar in the bin directory, called 'velocity-servlet-X.jar'. This jar contains utility code for servlet programmers. It has the same external dependency requirements as the regular jar target.
      • jar-J2EE 構(gòu)建一個完整的jar文件。和jar任務(wù)相似,該jar文件包含了J2EE應(yīng)用所需要的所有的組建。現(xiàn)在,多增加的文件就只有org.apache.velocity.runtime.resource.loader.DataSourceResourceLoader。和其他任務(wù)一樣,該jar文件也是放在bin文件夾下的,叫做velocity-j2ee-X.jar。注意,如果你希望使用該任務(wù),你必須將j2ee.jar拷貝到build/lib文件夾中。我們沒有在任何發(fā)布文件中提供該jar文件。在http://java.sun.com上能找到他。關(guān)于該jar文件的依賴組件和jar任務(wù)一樣,也沒有包括。builds a complete jar, like the 'jar' target, that includes any components that require J2EE support. Currently, this includes only org.apache.velocity.runtime.resource.loader.DataSourceResourceLoader. As usual, it is placed in the bin directory, called 'velocity-j2ee-X.jar'. NOTE : if you wish to use this build target, you must place (or link) a copy of j2ee.jar into the build/lib directory. We do not provide it as part of the distribution. A good source is http://java.sun.com/. It has the same external dependency requirements as the regular jar target.
      • jar-J2EE-dep build a complete jar with J2EE support and includes logging support from the Jakarta Avalon Logkit and regexp support fromt the Jakarta ORO package. See the notes on the jar-dep target, above.
      • examples 構(gòu)建在examples文件夾中的例子代碼。該任務(wù)同樣會構(gòu)建論壇例子項目。builds the example code in the example programs found in the examples directory. This build target will also build the forumdemo example project.
      • forumdemo 構(gòu)建在examples/forumdemo文件夾中的web應(yīng)用實例。builds the example webapplication in the examples/forumdemo directory.
      • docs 在docs文件夾中使用Anakia XML轉(zhuǎn)換工具構(gòu)建文檔。允許你在構(gòu)建中使用Velocity模版作為樣式表。注意,該任務(wù)需要把jakarta-site2項目放在jakarta-velocity發(fā)布文件夾中。關(guān)于更詳細的內(nèi)容請參看在build.xml文件中該任務(wù)的詳細說明。builds these docs in the docs directory using Velocity's Anakia XML transformation tool. Allowing you to use Velocity templates in place of stylesheets - give it a try! Note: This target requires that the jakarta-site2 project is located as a peer directory to the jakarta-velocity distribution directory. Please see the note in the build.xml file for this target for further information.
      • jar-src 將所有的Velocity代碼放在一個jar里面,置于bin文件夾中。bundles all the Velocity source code into a single jar, placed in the bin directory.
      • javadocs 在doc/api文件夾中構(gòu)建API文檔。builds the Javadoc class documentation in the docs/api directory
      • test (after jar) will test Velocity against it's testbed suite of test routines
      • help 列出所有可用的任務(wù)。lists the build targets that are available.
    5. 雖然不是必須的,但首先測試一下構(gòu)建是一個不錯的想法。使用test任務(wù)即可。While not required, testing the build is a good idea. Use the test target mentioned above.
    6. 所有的事情都OK了。Velocity已經(jīng)能開始工作了。將合適的jar文件置于你的類路徑中,或者放在合適的位置(比如web-inf/lib)That's it! Velocity is ready to be used. Put the jar into your classpath, or into other appropriate places (such as the lib directory of your webapp if using with servlets)
    7. 我們建議你先運行下例子來感受下Velocity。通過輸入ant examples來構(gòu)建。If you want to play with the examples, which is highly recommended when getting started, use build the examples via ant examples.

    依賴包Dependencies

    Velocity使用Java2 API。構(gòu)建Velocity需要Java2 SDK。要運行Velocity,需要Java2 RTE。Velocity uses elements of the Java 2 API such as collections, and therefore building requires the Java 2 Standard Edition SDK (Software Development Kit). To run Velocity, the Java 2 Standard Edition RTE (Run Time Environment) is required (or you can use the SDK, of course).

    Velocity為了完成一些通用的功能,需要一些額外的包。為了方便,他們都放在build/lib文件夾下,但是默認的構(gòu)建任務(wù)并沒有包含這些jar。如果你使用的是默認的任務(wù)構(gòu)建Velocity,你必須要把這些jar文件放入你的classpath。Velocity also is dependent upon a few packages for general functionality. They are included in the build/lib directory for convenience, but the default build target (see above) does not include them. If you use the default build target, you must add the dependencies to your classpath.

    • Jakarta Commons Collections - 必需的required.
    • Jakarta Avalon Logkit - 可選的,但是很常用。如果需要使用Velocity默認的基于文件的日志功能。optional, but very common. Needed if using the default file-based logging in Velocity.
    • Jakarta ORO - 可選的。如果要使用org.apache.velocity.convert.WebMacro 模版轉(zhuǎn)換工具。optional. Needed when using the org.apache.velocity.convert.WebMacro template conversion utility. 資源Resources 下面有一些例子和資源。我們建議你能看看我們提供的例子,文檔甚至源代碼。下面是一些很好的資源。There are quite a few resources and examples available to the programmer, and we recommend that you look at our examples, documentation and even the source code. Some great sources are :
    • 用戶和開發(fā)者的交流社區(qū):通過mail-lists加入我們。The user and developer community : join us via the mail-lists.
    • Mail-list資料庫: http://www.mail-archive.com 。在搜索框中輸入velocity來查看user和dev的文檔。Mail-list archives : http://www.mail-archive.com is a good one. Type 'velocity' into the search box to see both our -user and -dev archives.
    • 源代碼:在Velocity項目下的src/java文件夾中。source code : src/java/... : all the source code to the Velocity project
    • 應(yīng)用示例1:一個簡單的用于演示怎樣在一個應(yīng)用程序中使用Velocity。application example 1 : examples/app_example1 : a simple example showing how to use Velocity in an application program.
    • 應(yīng)用示例2:一個簡單的用于演示怎樣通過使用Velocity應(yīng)用程序工具包來在應(yīng)用程序中使用Velocity。application example 2 : examples/app_example2 : a simple example showing how to use Velocity in an application program using the Velocity application utility class.
    • servlet例子:一個簡單的用于演示怎樣在servlet中使用Velocity的例子。servlet example : examples/servlet_example1 : a simple example showing how to use Velocity in a servlet.
    • 日志例子:一個簡單的用于演示怎樣自定義一個日志記錄器并將它注冊到velocity中來接收日志消息的例子。logger example : examples/logger_example : a simple example showing how to create a custom logging class and register it with Velocity to receive all log messages.
    • XML例子:XML example : examples/xmlapp_example : a simple example showing how to use JDOM to read and access XML document data from within a Velocity template. It also includes a demonstration of a recursive Velocimacro that walks the document tree.
    • event 例子:一個用來演示在Velocity1.1中出現(xiàn)的事件處理API的使用。example : examples/event_example : An example that demonstrates the use of the event handling API in Velocity 1.1
    • Anakia 應(yīng)用:application : 一個用來演示怎樣使用Velocity來為XML數(shù)據(jù)創(chuàng)建樣式表。 examples/anakia : example application showing how to use Velocity for creating stylesheet renderings of xml data
    • 論壇Web演示應(yīng)用Forumdemo web app :一個基于servlet的論壇演示應(yīng)用。 examples/forumdemo : working example of a simple servlet-based forum application
    • documentation : docs : all the generated documentation for the Velocity project in html
    • API documentation : docs/api : the generated Javadoc documentation for the Velocity project
    • 模版:大量的關(guān)于模版的示例,這些都是極好的VTL的例子。templates : test/templates : a large collection of template examples in our testbed directory, these are a great source of useage examples of VTL, the Velocity Template Language
    • 上下文例子:兩個關(guān)于怎樣擴展上下文對象的例子,適用于高級用戶。context example : examples/context_example : two examples showing how the Velocity context can be extended. For advanced users.

    上面所有引用到的文件夾都是基于發(fā)布文件的根目錄的。All directory references above are relative to the distribution root directory. Velocity怎樣工作How Velocity Works 基本的格式'The Fundamental Pattern'

    當(dāng)你在一個應(yīng)用程序中或者一個servlet中,你一般會按照下面的方式來做。When using Velocity in an application program or in a servlet (or anywhere, actually), you will generally do the following :

    1. 初始化Velocity:對于兩種使用環(huán)境都適用------Singleton和separate rutime instance,并且該工作只需做一次。Initialize Velocity. This applies to both usage patterns for Velocity, the Singleton as well as the 'separate runtime instance' (see more on this below), and you only do this once.
    2. 創(chuàng)建一個上下文對象(后面將詳細介紹)。Create a Context object (more on what that is later).
    3. 把你的數(shù)據(jù)對象放入上下文對象中。Add your data objects to the Context.
    4. 選擇一個模版。Choose a template.
    5. 把模版和你的數(shù)據(jù)一起輸出。'Merge' the template and your data to produce the ouput.

    在代碼中,通過類org.apache.velocity.app.Velocity使用Singleton模式,代碼如下:In code, using the singleton pattern via the org.apache.velocity.app.Velocity class, this looks like import java.io.StringWriter;

    import org.apache.velocity.VelocityContext;
    import org.apache.velocity.Template;
    import org.apache.velocity.app.Velocity;
    import org.apache.velocity.exception.ResourceNotFoundException;
    import org.apache.velocity.exception.ParseErrorException;
    import org.apache.velocity.exception.MethodInvocationException;
    Velocity.init();
    VelocityContext context = new VelocityContext();
    context.put( "name", new String("Velocity") );
    Template template = null;
    try
    {
    template = Velocity.getTemplate("mytemplate.vm");
    }
    catch( ResourceNotFoundException rnfe )
    {
    // couldn't find the template
    }
    catch( ParseErrorException pee )
    {
    // syntax error : problem parsing the template
    }
    catch( MethodInvocationException mie )
    {
    // something invoked in the template
    // threw an exception
    }
    catch( Exception e )
    {  
    }
    StringWriter sw = new StringWriter();
    template.merge( context, sw );

    這就是基本的格式。很簡單,不是嗎?這基本上就是你使用Velocity來合成模版所需要的步驟。當(dāng)然在實際的應(yīng)用中你不會像這樣書寫代碼,我們?yōu)閟ervlet和普通應(yīng)用提供了一些工具,讓你能甚至比上面的代碼更容易的使用Velocity。在本指南的后面,我們將介紹在servlet和普通應(yīng)用中使用Velocity的更多細節(jié),和那些不錯的工具。在每一種情況下,當(dāng)然,上面的運行的順序是不變的,或者在幕后是這樣的。That's the basic pattern. It is very simple, isn't it? This is generally what happens when you use Velocity to render a template. You probably won't be writing code exactly like this - we provide a few tools to help make it even easier than this for both servlet and application programmers. Later on in this guide, we will talk about using Velocity in both servlets as well as general applications, and we discuss the tools we provide to make things easier. In each case, though, the above sequence is what is happening either explicitly, or behind the scenes. 使用singleton或者不...To Singleton Or Not To Singleton... 在Velocity1.2之后,開發(fā)人員就有了兩種使用Velocity引擎的選擇------單例模式或者非單例模式。兩中選擇都使用的是相同的Velocity代碼,讓Velocity更簡單的融入到你的Java應(yīng)用中。As of Velocity 1.2 and later, developers now have two options for using the Velocity engine, the singleton model and the separate instance model. The same core Velocity code is used for both approaches, which are provided to make Velocity easier to integrate into your Java application.

    單例模式Singleton Model

    這是一種老的模式,即在JVM中只存在一個Velocity引擎的實例,整個應(yīng)用共享這一個。這種方式對于配置文件的定位和共享資源都是很方便的。比如,該模式極其適合使用在Servlet2.2+標(biāo)準(zhǔn)下的web應(yīng)用中------每個web應(yīng)用都擁有其唯一的一個Velocity實例,允許web應(yīng)用的servlet共享諸如模版,日志記錄器等資源。這個單例的實例可以通過org.apache.velocity.app.Velocity.app.Velocity類創(chuàng)建。下面是一個使用單例模式的例子:This is the legacy pattern, where there is only one instance of the Velocity engine in the JVM (or web application, depending) that is shared by all. This is very convenient as it allows localized configuration and sharing of resources. For example, this is a very appropriate model for use in a Servlet 2.2+ compliant web application as each web application can have it's own instance of Velocity, allowing that web application's servlet to share resources like templates, a logger, etc. The singleton is accessable via the org.apache.velocity.app.Velocity class, and and example of use : import org.apache.velocity.app.Velocity;

    import org.apache.velocity.Template;
    ...
    /*Configure the engine - as an example, we are usingourselves as the logger - see logging examples*/
    Velocity.setProperty( Velocity.RUNTIME_LOG_LOGSYSTEM, this);
    /*now initialize the engine*/
    Velocity.init();
    ...
    Template t = Velocity.getTemplate("foo.vm");

    請注意,在org.apache.velocity.servlet.VelocityServlet 基礎(chǔ)類(一個用于使創(chuàng)建servlet更簡單的工具類)中,使用的就是單例模式。通過繼承該類創(chuàng)建使用Velocity的servlet是最簡單和最方便的方式,當(dāng)然,這不是必須的。serbletPlease note that the Singleton model is used in the org.apache.velocity.servlet.VelocityServlet base class, a utility class provided with the distribution to make writing servlets easier. While extending this class is the most common and convenient way to write servlets using Velocity, you are free to not use this class if you needs require something different.

    分離的實例Separate Instance

    在1.2中的新出現(xiàn)的分離的實例模式允許你在一個JVM中創(chuàng)建,配置和使用許多Velocity引擎的實例。如果你想在同一個應(yīng)用中為不同的Velocity引擎配置不同的資源,模版,日志記錄器等,這種方式特別有用。通過使用org.apache.velocity.app.VelocityEngine來創(chuàng)建分離實例模式。下面是一個例子,功能同上一個例子:New in version 1.2, the separate instance allows you to create, configure and use as many instances of Velocity as you wish in the same JVM (or web application.) This is useful when you wish to support separate configurations, such as template directories, loggers, etc in the same application. To use separate instances, use the org.apache.velocity.app.VelocityEngine class. An example, which parallels the above singleton example, looks like :

    import org.apache.velocity.app.[VelocityEngine];
    import org.apache.velocity.Template;
    ...
    /*create a new instance of the engine*/
    VelocityEngine ve = new VelocityEngine();
    /*configure the engine. In this case, we are usingourselves as a logger (see logging examples..)*/
    ve.setProperty( VelocityEngine.RUNTIME_LOG_LOGSYSTEM, this);
    /*initialize the engine*/
    ve.init();
    ...
    Template t = ve.getTemplate("foo.vm");

    如你所見,這是很簡單并且很直接的。除了一些簡單的形式上的改變,使用單例模式還是分離模式對于你應(yīng)用的高層次的架構(gòu)和模版是沒有影響的。As you can see, this is very simple and straightforward. Except for some simple syntax changes, using Velocity as a singleton or as separate instances requires no changes to the high-level structure of your application or templates.

    作為一個程序員,需要強調(diào)的是使用org.apache.velocity.app.Velocity類來應(yīng)用單例模式,使用org.apache.velocity.app.VelocityEngine類來應(yīng)用非單例模式(分離實例模式)。As a programmer, the classes you should use to interact with the Velocity internals are the org.apache.velocity.app.Velocity class if using the singleton model, or org.apache.velocity.app.VelocityEngine if using the non-singleton model ('separate instance').

    另外,不要使用在org.apache.velocity.runtime包中的Runtime,RuntimeConstants,RuntimeSingleton或者RuntimeInstance類。這些類是用于框架內(nèi)部的,并且在不斷的變化中。正如上面提到的,你應(yīng)該使用在org.apache.vleocity.app包中的類------Velocity和VelocityEngine。At no time should an application use the internal Runtime, RuntimeConstants, RuntimeSingleton or RuntimeInstance classes in the org.apache.velocity.runtime package, as these are intended for internal use only and may change over time. As mentioned above, the classes you should use are located in the org.apache.velocity.app package, and are the Velocity and VelocityEngine classes. If anything is missing or needed from those classes, do not hesitate to suggest changes - these classes are intended for the application developer. 上下文對象The Context 基礎(chǔ)The Basics
    Velocity是以上下文概念為中心的,并且這是一種普通的在系統(tǒng)的各個部分中傳遞數(shù)據(jù)容器的技術(shù)??梢赃@樣認為,上下文是在Java層(程序員關(guān)注的)和模版層(設(shè)計人員關(guān)注的)之間數(shù)據(jù)的負載者。程序員會將所有應(yīng)用需要的對象,無論什么類型都聚集在一起,放入上下文中。對于頁面設(shè)計者,在上下文中的對象,和它們的屬性及方法都通過叫做引用的模版元素來調(diào)用。一般來說,你需要和設(shè)計者一起設(shè)計在頁面上需要顯示的數(shù)據(jù),這些會成為設(shè)計者在頁面中需要使用的API。所以,在這個階段的時間的投入和仔細的分析是很值得的。The concept of the 'context' is central to Velocity, and is a common technique for moving a container of data around between parts of a system. The idea is that the context is a 'carrier' of data between the Java layer (or you the programmer) and the template layer ( or the designer ). You as the programmer will gather objects of various types, whatever your application calls for, and place them in the context. To the designer, these objects, and their methods and properties, will become accessable via template elements called references. Generally, you will work with the designer to determine the data needs for the application. In a sense, this will become an 'API' as you produce a data set for the designer to access in the template. Therefore, in this phase of the development process it is worth devoting some time and careful analysis.

    同時,Velocity允許你創(chuàng)建自己的上下文對象來支持特別的要求和技術(shù)(比如連接一個LDAP的上下文)。一個很好的擴展點是繼承VelocityContext類。While Velocity allows you to create your own context classes to support special needs and techniques (like a context that accesses an LDAP server directly, for example), a good basic implementation class called VelocityContext is provided for you as part of the distribution.

    VelocityContext滿足一般的需要,并且我們強烈建議你使用它。只有在例外或者高級的情況下,你需要繼承或者創(chuàng)建你自己的上下文對象。VelocityContext is suitable for all general purpose needs, and we strongly recommended that you use it. Only in exceptional and advanced cases will you need to extend or create your own context implementation.

    使用VelocityContext和使用普通的Java Hashtable對象差不多。你需要的最主要的兩個方法是:Using VelocityContext is as simple as using a normal Java Hashtable class. While the interface contains other useful methods, the two main methods you will use are public Object put(String key, Object value);
    public Object get(String key);

    請注意這和Hashtable相似,里面的值必須繼承自java.lang.Object,并且不是null。基礎(chǔ)類型,比如int或者float必須要用適當(dāng)?shù)陌b類包裝才能使用。Please note that like a Hashtable, the value must be derived from java.lang.Object, and must not be null. Fundamental types like int or float must be wrapped in the appropriate wrapper classes.

    這就是context基礎(chǔ)的操作。需要了解更多的信息 ,請參考發(fā)布文件中的API文檔。That's really all there is to basic context operations. For more information, see the API documentation included in the distribution.

    使用*#foreach()來遍歷對象{*}Support for Iterative Objects for #foreach()

    作為一個程序員,對于放入上下文中的對象你有很大的自由度。在最大范圍的自由度里需要遵守一些規(guī)則,所以,理解Velocity支持什么,就不會有錯誤會發(fā)生了。Velocity支持幾種適合在VTL使用#foreach()指示符的集合類型對象。As a programmer, you have great freedom in the objects that you put into the context. But as with most freedoms, this one comes with a little bit of responsibility, so understand what Velocity supports, and any issues that may arise. Velocity supports serveral types of collection types suitable for use in the VTL #foreach() directive.

    • Object []正規(guī)的對象數(shù)組,在這里不需要再多說了。Velocity在框架內(nèi)部用一個實現(xiàn)了Iterator接口的類來包裝你的數(shù)組,具體的包裝細節(jié)作為一個程序員或者模版設(shè)計者不需要過多的關(guān)注。Regular object array, not much needs to be said here. Velocity will internally wrap your array in a class that provides an Iterator interface, but that shouldn't concern you as the programmer, or the template author.
    • java.util.Collection Velocity會使用iterator()方法來得到一個Iterator對象來執(zhí)行遍歷操作。所以,你需要使你的對象實現(xiàn)Collection接口,以使iterator()方法返回一個正常的Iterator對象。Velocity will use the iterator() method to get an Iterator to use in the loop, so if you are implementing a Collection interface on your object, please ensure that iterator() returns a working Iterator.
    • java.util.Map這里,Velocity依靠values()方法來得到一個Collection接口,然后再調(diào)用iterator()方法來得到用來遍歷的Iterator對象。Here, Velocity depends upon the values() method of the interface to get a Collection interface, on which iterator() is called to retrieve an Iterator for the loop.
    • java.util.Iterator 小心使用:這是最近才支持的,不過最好是作為臨時的使用,主要是因為Iterator的不可復(fù)位性決定的。如果一個Iterator直接被放入上下文,并且使用了多于一個的#foreach來遍歷,那么第二個#foreach就會失敗,因為Iterator并沒有復(fù)位。USE WITH CAUTION : This is currently supported only provisionally - the issue of concern is the 'non-resettablity' of the Iterator. If a 'naked' Iterator is placed into the context, and used in more than one #foreach(), subsequent #foreach() blocks after the first will fail, as the Iterator doesn't reset.
    • java.util.Enumeration 小心使用:和Iterator相似,這也是最近才支持的用于臨時性的。原因也是Enumeration的不可復(fù)位性決定的。同樣,如果一個Enumeration直接被放入上下文,并且使用了多于一個的#foreach來遍歷,那么第二個#foreach就會失敗,因為Enumeration并沒有復(fù)位。USE WITH CAUTION : Like java.util.Iterator, this is currently supported only provisionally - the issue of concern is the 'non-resettablity' of the Enumeration. If a 'naked' Enumeration is placed into the context, and used in more than one #foreach(), subsequent #foreach() blocks after the first will fail, as the Enumeration doesn't reset.

    我們建議,只有在必須的時候,才將Iterator 和Enumeration放入上下文中。In the case of the Iterator and Enumeration, it is recommended that they are placed in the context only when it cannot be avoided, and you should let Velocity find the appropriate reusable iterative interface when that is sufficient and possible.

    盡管可能有充足理由直接在Context中使用Iterator(比如通過JDBC得到的大的數(shù)據(jù)集),但如果能夠避免,最好還是使用其他的代替。這里直接使用是指象下面代碼這樣:There are good reasons to use the java.util.Iterator interface directly (large data sets via JDBC, for example), but if it can be avoided, it might be better to use something else. By 'directly' , we meant doing something like: Vector v = new Vector();
    v.addElement("Hello");
    v.addElement("There");

    context.put("words", v.iterator() );

    在上面的例子中,Iterator對象自己是放入了Context。作為代替,只需象這樣:where the Iterator itself is placed into the context. Instead, if you simply did: context.put("words", v );

    這樣一切都能正常運行:Velocity將會發(fā)現(xiàn)Vector實現(xiàn)了Collection,并且會找到iterator()方法,并且在每一次調(diào)用#foreach之前刷新Iterator對象。如果使用的直接是Iterator對象,那么一旦velocity在其上使用了一次#foreach,Velocity沒有辦法再重新得到一個新的Iterator。這將導(dǎo)致所有在#foreach中使用該引用輸出為空。then all would be fine: Velocity would figure out that Vector implement Collection (via List), and therefore will find the iterator() method, and use that to get a 'fresh' Iterator for its use each time it needs to. With just a plain Iterator (the first snippet above...), once velocity has used it in a #foreach(), Velocity has no way of getting a new one to use for the next #foreach() it is used in. The result is no output from any subsequent #foreach() blocks using that reference.

    上面的介紹并不是說在Velocity中遍歷對象是一件必須經(jīng)過細致考慮的問題。不過,當(dāng)你放入上下文中的是一個Iterator,確實需要小心謹慎。This above isn't meant to give the impression that iterating over collections in Velocity is something that requires great care and thought. Rather, the opposite is true, in general. Just be careful when you place an Iterator into the context.

    上下文鏈Context Chaining

    Velocity的上下文設(shè)計中的一個革命性的創(chuàng)新是加入了上下文鏈的概念,有時候也稱為上下文包裝。這種思想讓你能將分散的上下文對象連接起來,并看作一個聯(lián)合的上下文對象來使用。An innovative feature of Velocity's context design is the concept of context chaining. Also sometimes referred to as context wrapping, this advanced feature allows you to connect separate contexts together in a manner that makes it appear as one 'contiguous' context to the template.

    最好使用一個例子來演示一下:This is best illustrated by an example : VelocityContext context1 = new VelocityContext();

    context1.put("name","Velocity");
    context1.put("project", "Jakarta");
    context1.put("duplicate", "I am in context1");VelocityContext context2 = new VelocityContext( context1 );context2.put("lang", "Java" );
    context2.put("duplicate", "I am in context2");template.merge( context2, writer );

    在上面的例子中,我們建立連接context1的context2。這意味著在末拌種,你可以使用任何放在這兩個上下文中的對象(但這時不能存在使用同樣的key來放入對象)。如果這樣做了(使用了重復(fù)的key來保存對象),在比較后面定義(外層)的上下文中的那個對象將有效。比如在上面的例子中,如果使用duplicate來引用,得到的將會是"I am in context2"In the code above, we have set up context2 such that it chains context1. This means that in the template, you can access any of the items that were put into either of the two VelocityContext objects, as long as there is no duplication of the keys used to add objects. If that is the case, as it is above for the key 'duplicate', the object stored in the nearest context in the chain will be available. In this example above, the object returned would be the string "I am in context2".

    注意這種重復(fù)定義(或者叫做覆蓋定義),對被覆蓋了的對象沒有任何害處或者改變。所以,在上面的例子中,字符串"I am in context1"仍然存在并狀態(tài)良好,并且如果通過使用context1.get("duplicate")就能正確地得到。但在上面的例子中,在模版中使用$duplicate的引用會得到"I am in context2"的值,并且模版上的引用不可能得到"I am in context1"。Note that this duplication, or 'covering', of a context item does not in any way harm or alter the covered object. So in the example above, the string "I am in context1" is alive and well, still accessable via context1.get("duplicate"). But in the example above, the value of the reference '$duplicate' in the template would be 'I am in context2', and the template has no access to the covered string 'I am in context1'.

    注意,如果你依賴從模版中向上下文添加一些在合成時需要檢查的狀態(tài)值,你需要小心。通過在模版中使用#set來改變上下文中的值得時候,只會影響最外層的上下文。所以,確保如果你不希望從模版中改變內(nèi)層上下文的值得時候,不要丟棄外層的上下文。Note also that you have to be careful when you are relying on the template to add information to a context that you will examine later after the rendering. The changes to the context via #set() statements in a template will affect only the outer context. So make sure that you don't discard the outer context, expecting the data from the template to have been placed onto the inner one.

    This feature has many uses, the most common so far is providing layered data access and toolsets.

    如同前面所介紹的,Velocity的上下文機制也是能被擴展的,不過這超越了本指南的范圍。如果你對這感興趣,請參看在org.apache.velocity.context包中的類是怎樣提供上下文對象并把它們聯(lián)合起來的。同時,在examples/context_example目錄下,也有一些例子演示了怎樣擴展上下文,包括了使用數(shù)據(jù)庫來作為上下文對象的例子(雖然這是個很愚蠢的想法)。As mentioned before, the Velocity context mechanism is also extendable, but beyond the current scope of this guide. If you are interested, please see the classes in the package org.apache.velocity.context to see how the provided contexts are put together. Futher, there are a few examples in the examples/context_example directory in the distribution which show alternate implementations, including [a goofy] one that uses a database as the backing storage.

    請注意這些例子僅僅用于演示,而沒有被驗證實用價值。Please note that these examples are unsupported and are there for demonstration/educational purposes only.

    在模版中創(chuàng)建的對象Objects Created in the Template
    有兩種情況下,Java代碼需要處理在運行時從模版中創(chuàng)建的對象。There are two common situations where the Java code must deal with objects created at runtime in the template :

    當(dāng)一個模版的作者調(diào)用了一個放在上下文中的用Java編寫的對象的方法的時候:When a template author calls a method of an object placed into the context by Java code. #set($myarr = "a","b","c" )
    $foo.bar( $myarr )

    當(dāng)一個模版向上下文中添加了一些在模版合成之后,Java代碼需要處理的對象時。When a template adds objects to the context, the Java code can access those objects after the merge process is complete. #set($myarr = "a","b","c" )
    #set( $foo = 1 )
    #set( $bar = "bar")

    處理這些情況只需要了解一些事實:Dealing with these cases if very straighforward, as there are just a few things to know:

    • 在VTL中當(dāng)把一個范圍操作[1..10]或者和對象數(shù)組["a","b"]放入上下文中是java.util.ArrayList對象。因此,當(dāng)你設(shè)計的方法是需要接受一個數(shù)組的時候,請注意這一點。The VTL RangeOperator [ 1..10 ] and ObjectArray ["a","b"] are java.util.ArrayList objects when placed in the context or passed to methods. Therefore, your methods that are designed to accept arrays created in the template should be written with this in mind.
    • 數(shù)字將作為Integer放入上下文中,字符串是String。Numbers will be Integers in the context, and strings will be, of course, Strings.
    • 在方法調(diào)用的時候,Velocity也會接受原始值。比如通過#set放入上下文中的一個Integer也能調(diào)用setFoo(int i)方法。Velocity will properly 'narrow' args to method calls, so calling setFoo( int i ) with an int placed into the context via #set() will work fine.

    關(guān)于上下文的其他問題Other Context Issues

    One of the features provided by the VelocityContext (or any Context derived from AbstractContext) is node specific introspection caching. Generally, you as a the developer don't need to worry about this when using the VelocityContext as your context. However, there is currently one known usage pattern where you must be aware of this feature.

    The VelocityContext will accumulate intropection information about the syntax nodes in a template as it visits those nodes. So, in the following situation:

    • You are iterating over the same template using the same VelocityContext object.
    • Template caching is off.
    • You request the Template from getTemplate() on each iteration.

    It is possible that your VelocityContext will appear to 'leak' memory (it is really just gathering more introspection information.) What happens is that it accumulates template node introspection information for each template it visits, and as template caching is off, it appears to the VelocityContext that it is visiting a new template each time. Hence it gathers more introspection information and grows. It is highly recommended that you do one or more of the following :

    • Create a new VelocityContext for each excursion down through the template render process. This will prevent the accumulation of introspection cache data. For the case where you want to reuse the VelocityContext because it's populated with data or objects, you can simply wrap the populated VelocityContext in another, and the 'outer' one will accumulate the introspection information, which you will just discard. Ex. VelocityContext useThis = new VelocityContext( populatedVC ); This works because the outer context will store the introspection cache data, and get any requested data from the inner context (as it is empty.) Be careful though - if your template places data into the context and it's expected that it will be used in the subsequent iterations, you will need to do one of the other fixes, as any template #set() statements will be stored in the outermost context. See the discussion in Context chaining for more information.
    • Turn on template caching. This will prevent the template from being re-parsed on each iteration, resulting the the VelocityContext being able to not only avoid adding to the introspection cache information, but be able to use it resulting in a performance improvement.
    • Reuse the Template object for the duration of the loop iterations. Then you won't be forcing Velocity, if the cache is turned off, to reread and reparse the same template over and over, so the VelocityContext won't gather new introspection information each time. 在Servlets中使用Velocity

    Using Velocity In Servlets

    Servlet編程Servlet Programming

    Velocity最常用的地方就是在Web應(yīng)用中的Java Servlet編程了。有許多理由來解釋為什么Velocity很適合這樣工作,其中最主要的一個就是Velocity的強制性的將視圖層和邏輯層分開了。有許多關(guān)于這方面的資料,包括這個。The most common use of Velocity is in the area of Java Servlet programming for the WWW. There are many reasons why Velocity is well suited for this task, one of the primary ones is Velocity's enforcement of the separation of the presentation (or view) layer from the code layer. There are many resources on this subject, including this.

    把Velocity應(yīng)用于servlet環(huán)境的基礎(chǔ)技術(shù)是很簡單的,所有你需要做的就是繼承VelocityServlet基礎(chǔ)類,并實現(xiàn)一個handleRequest()方法,這就是全部。The basic technique of using Velocity in a servlet environment is very simple. In a nutshell, all you must do is extend the provided VelocityServlet base class and implement a single method, handleRequest(). That's really all that is required to use Velocity in your servlet development.

    對于Velocity1.1,有兩個方法需要實現(xiàn):As of Velocity 1.1, there are two handleRequest() methods :

    public Template handleRequest( Context ) 這是比較老的一個方法,這個方法要求你返回一個合法的Template對象。如果該對象無效或者為null,則被認為是一個錯誤的狀態(tài),并使用error()錯誤處理方法來處理。如果需要,你可以覆蓋error()方法。如果該方法返回null也是你希望的一個正確的返回值(比如你想重定向請求),建議你使用下面一個比較新的方法。This is the older of the two methods. This method requires that you return a valid Template object. If not valid, or null, this is considered an error condition, and will result in the error() error handling method being called. You may override the error() if you wish. If returning a null is something you expect to do (for example, you will want to redirect requests) it is recommended that you use the newer method, listed next.
    public Template handleRequest( HttpServletRequest, HttpServletResponse, Context ) 這個方法比較新,在1.1中實現(xiàn)。這兩者最大的區(qū)別在于在這個方法中,HttpServletReuqest和HttpServletResponse對象是作為參數(shù)傳遞給方法的。靈鴿一個不同的地方在于這個方法允許返回一個null來表明在該方法中所有的處理已經(jīng)做完了,Velocity只能再調(diào)用requestCleanup()方法。這個方法在你需要重定向請求的時候特別有用。This is the newer of the two handleRequest() methods, implemented in version 1.1. The difference with this method is that the HttpServletRequest and HttpServletResponse objects are passed to you as arguments to the method, as well as in the Context. The other difference is that this method can return null to indicate that all processing has been handled by the method, and that Velocity should do nothing further than call requestCleanup(). This is extremely useful is you wish to redirect the request, for example. 同樣,請參看Javadoc API文檔來得到更多的信息。As always, please refer to the Javadoc API documentation for the definitive and latest notes.
    下面這個例子和在發(fā)布文件中的SampleServlet.java文件(在example文件夾下)相似。The following code is similar to the SampleServlet.java class included in the distribution in the examples directory.

    public class SampleServlet extends VelocityServlet
    {
    public Template handleRequest( HttpServletRequest request,
    HttpServletResponse response,
    Context context )
    {String p1 = "Jakarta";
    String p2 = "Velocity";Vector vec = new Vector();
    vec.addElement( p1 );
    vec.addElement( p2 );context.put("list", vec );Template template = null;try
    {
    template = getTemplate("sample.vm");
    }
    catch( ResourceNotFoundException rnfe )
    {
    // couldn't find the template
    }
    catch( ParseErrorException pee )
    {
    // syntax error : problem parsing the template
    }
    catch( Exception e )
    {}return template;
    }
    }

    很眼熟?創(chuàng)建上下文對象的錯誤處理在VelocityServlet中已經(jīng)處理,并且merge()方法的調(diào)用也在Velocity基礎(chǔ)類中處理了。總的來說,這和我們在介紹Velocity的使用的基本格式的時候是一致的。在該例子中,我們向context中放入了一些應(yīng)用數(shù)據(jù),然后返回了一個模版。Look familiar? With the exception of creating the context object, which is done for you by the VelocityServlet base class, and the merge() step which is also done for you by the VelocityServlet base class, it's identical to the basic code pattern we mentioned at the beginning of this guide. We take the context, add our application data, and return a template.

    在傳入方法(第一個方法)的Context對象中,保存了當(dāng)前的HttpServletRequest和HttpServletResponse對象。他們使用VelocityServlet.REQUEST(value="req")和Velocity.RESPONSE(VALUE="RES")常量來引用。要在你的代碼中使用這些對象,象下面這樣做:The default Context object that is passed into the handleRequest() methods contains both the current HttpServletRequest and HttpServletResponse objects. They are placed in the context using the the constants VelocityServlet.REQUEST (value = 'req') and VelocityServlet.RESPONSE (value = 'res') respectively. To access and use these objects in your Java code : public Template handleRequest( Context context )
    {
    HttpServletRequest request = (HttpServletRequest) context.get( REQUEST );
    HttpServletResponse response = (HttpServletResponse) context.get( RESPONSE );

    ...

    或者在你的模版中這樣引用:and in your templates: #set($name = $req.getParameter('name') )

    如果需要更高級的使用,VelocityServlet基礎(chǔ)類允許你覆蓋請求處理的一些部分,下面的這些方法可能是一個擴展點:For more advanced uses, the VelocityServlet base class allows you to override parts of the handling of the request processing. The following methods may be overridden :

    Properties loadConfiguration( ServletConfig ) 允許你覆蓋普通的配置機制并且添加或者修改一些配置屬性。覆蓋這個方法用來覆蓋或者參數(shù)化模版和日志的路徑,該路徑需要基于webapp root的絕對路徑。Allows you to override the normal configuration mechanism and add or alter the configuation properties. This is useful for overriding or augmenting template and log paths, to set the absolute path into the webapp root at runtime.

    Context createContext(HttpServletRequest, HttpServletResponse ) 與許你創(chuàng)建自己的Context對象。這在需要更高級的情況下使用,比如需要鏈化或者預(yù)加載一些工具或者數(shù)據(jù)。默認的該方法的實現(xiàn)簡單的返回了一個包含了HttpServletRequest和HttpServletResponseVelocityContext對象。請求和響應(yīng)對象使用簡單的包裝類包裝,以避免在一些servlet容器中自省時會發(fā)生的錯誤。但你可以象平常一樣使用其中的request和response對象,或者從模版中引用其方法。只需要注意一點,就是他們不再是javax.servlet.XXXX類了,如果你需要使用類全名的時候,需要重視。Allows you to create the Context object yourself. This allows more advanced techniques, such as chaining or pre-loading with tools or data. The default implementation simply returns a VelocityContext object with the request and response objects placed inside. The request and response objects are wrapped in simple wrapper classes to avoid introspection problems that may occurr in some servlet container implementations. You can use the request and repsponse objects normally, accessing methods of either from the template. Just note that they aren't specifically javax.servlet.XXXX classes, if that is important to you.

    void setContentType( HttpServletRequest,HttpServletResponse ) 允許你檢查請求,并設(shè)置內(nèi)容類型(content type)。默認的類型是根據(jù)Velocity.properties中規(guī)定的。如果沒有在properties文件中設(shè)定,或者說在默認情況下,"text/html"將是內(nèi)容類型。Allows you to examine the request and set the content type yourself, depending on the request or client. The default implementation sets the content type to be that either specified in the velocity.properties, if any, or the default, "text/html" if not specified in the properties.

    void mergeTemplate( Template, Context, HttpServletResponse ) 允許你創(chuàng)建輸出流。VelocityServlet使用了一個很有效的Writer類的緩存池,所以在一般情況下,該方法不會被覆蓋。Allows you to produce the output stream. The VelocityServlet uses a pool of very efficient Writer classes, so this would usually be overridden in special situations.

    void requestCleanup( HttpServletRequest, HttpServletResponse , Context ) 允許你在請求處理結(jié)束后做一些清理工作或者資源的回收工作。默認的方法沒有做任何事情。Allows you to do any cleanup or resource reclamation at the end of the request processing. The default does nothing.

    protected void error( HttpServletRequest, HttpServletResponse, Exception ) 如果在請求處理中出現(xiàn)異常,就將調(diào)用該方法來處理異常。默認的處理將會返回一個普通的帶有棧信息和錯誤信息的HTML頁面給用戶。覆蓋該方法提供更人性化的錯誤提示或者異常處理。Error handler that is called an exception occurrs in request processing. Default implementation will send a simple HTML message with stacktrace and exception information back to the user. Override for custom client messages and more advanced problem handling.

    更多的信息請參見Javadoc API文檔。For further information, please see the Javadoc API documentation.

    部署Deployment

    當(dāng)你部署基于Velocity的servlet應(yīng)用,你試圖確定你的配置文件被用來配置了Velocity引擎。在Tomcat下,達到該目的的方法之一是將你的velocity.properties文件放在你的web應(yīng)用的根目錄下(webapps/appname),并在你的WEB-INF/web.xml文件后面加上:When you deploy your Velocity-based servlets, you will certainly want to ensure that your properties file is used to configure the Velocity runtime. Under Tomcat, one way to accomplish this is by placing your velocity.properties file into the root directory of your web app (webapps/appname ) and then add the following to your WEB-INF/web.xml file : <servlet>
    <servlet-name>MyServlet</servlet-name>
    <servlet-class>com.foo.bar.MyServlet</servlet-class>
    <init-param>
    <param-name>properties</param-name>
    <param-value>/velocity.properties</param-value>
    </init-param>
    </servlet>

    假設(shè)一切正常,在MyServlet被加載的時候,會使用velocity.prooetries文件來初始化Velocity引擎。Assuming all is right, this will ensure that when MyServlet is loaded, it will use the velocity.properties file to initialize itself rather than relying on it's internal defaults.

    注意Velocity在它的核心的Runtime類中使用的是單例模式,所以,把velocitypXX.jar放在WEB-INF/lib文件夾中會是一個更好的選擇。Note that Velocity uses a singleton model for it's central core Runtime class, so it is a very good idea to put the velocity-XX.jar into the WEB-INF/lib directory in all web applications that use Velocity to ensure that the web app classloader is managing your Runtime instance, rather than putting it in the CLASSPATH or the top level lib directory of the servlet runner.

    這種部署方式能確保在不同的web應(yīng)用中使用的Velocity配置不會沖突。This deployment method will ensure that different web applications will not be subject to Velocity configuration conflicts. 在普通的應(yīng)用中使用Velocity

    Using Velocity In General Applications

    Velocity被設(shè)計為一個通用的工具,在一般的應(yīng)用中,Velocity也很有用。概括地說,在一般的應(yīng)用中,使用Velocity的基本結(jié)構(gòu)和在本指南開始介紹的那個結(jié)構(gòu)一致,和VelocityServlet提供給了編寫Servlet的便利性一樣,Velocity也為一般的應(yīng)用提供了一些工具類。作為一個一般應(yīng)用的程序員,你的一個新的責(zé)任就是初始化Velocity運行時引擎(Velocity runtime engine),但這也很簡單。As Velocity was designed to be a general-use tool, it is just as useful in general application programs as it is servlets. In general, you can use the same programming pattern discussed at the beginning of this guide, but there are a few utility methods provided for application use, just like we provide the VelocityServlet base class for ease of use in servlet programming. The only new responsibility you have as the application programmer is to initialize the Velocity runtime engine, but that is easy.

    The Velocity Helper Class

    Velocity包含了一個為一般應(yīng)用準(zhǔn)備的工具類,叫做Velocity(org.apache.velocity.Velocity)。提供該類的目的在于提供一些初始化Velocity必須的方法和一些有用的日常工具方法,讓使用Velocity更加方便。這個類在Javadoc中有詳細記錄,如有需要,請參考該文檔。在這里,該文檔只是作為一個指南,而Javadoc則提供了最完整的API的信息。Velocity contains an application utility class called Velocity ( org.apache.velocity.app.Velocity ). The purpose of this class is to provide the necessary methods required to initialize Velocity, as well as useful utility routines to make life easier in using Velocity. This class is documented in the project's javadoc, so please look there for definitive details. This documentation is intended to be of a tutorial nature; therefore for compete API information, the Javadoc is the definitive source.

    Velocity運行時引擎是一個單例的實例,在一個JVM中為所有的Velocity用戶提供資源,日志記錄,和其他的服務(wù)。不過,運行時引擎只需要初始化一次即可。你可能會嘗試多次初始化該引擎,但只有第一次的初始化操作是成功的,之后的嘗試會直接被忽略?,F(xiàn)在的Velocity工具類提供了5個方法來配置運行時引擎。The Velocity runtime engine is a singleton instance that provides resource, logging and other services to all Velocity users running in the same JVM. Therefore, the runtime engine is initialized only once. You can attempt to initialize Velocity more than once, but only the first initialization will apply. The rest of the attempts will be ignored. The Velocity utility class currently provides five methods used in configuration of the runtime engine.

    這5個方法分別為:The five configuration methods are :

    • setProperty( String key, Object o )
      給屬性key賦值o。該值一般為一個String,但在特殊的情況下,可以是用逗號分隔了的列表值(在一個String中,比如:"foo,bar,woogie")或者其他的一些東西。Sets the property key with the value o. The value is typically a String, but in special cases can also be a comma-separated list of values (in a single String, ex."foo, bar, woogie") as well as other things that will arise.
    • Object getProperty( String key )
      返回屬性key的值。注意你必須強制的轉(zhuǎn)化類型,不然,返回的總是String。Returns the value of the property key. Note that you must be aware of the type of the return value, as they can be things other than Strings.
    • init()
      使用分發(fā)包中的屬性初始化運行時狀態(tài)。(這些值在下面的關(guān)于屬性小節(jié)中列出)Initializes the runtime with the default properties provided in the distribution.(These are listed below in the section pertaining to properties.)
    • init( Properties p )
      使用參數(shù)中傳入的java.util.Properties對象中包含的屬性來初始化運行時狀態(tài)。Initialize the runtime with the properties contained in the java.util.Properties object passed as an argument.
    • init( String filename )
      使用參數(shù)中傳入的文件路徑對應(yīng)的屬性文件來初始化運行時狀態(tài)。initilizes the runtime using the properties found in the properties file filename

    注意,不論使用哪種方法,默認的屬性都會作為基礎(chǔ)的配置,所有增加的或者修改了的屬性都會覆蓋對應(yīng)的默認的配置。沒有被覆蓋的屬性仍然起作用。這樣的好處是只有你關(guān)注的屬性才被指定,而不需要把所有的屬性都指定出來。Note that in each case, the default properties will be used as a base configuration, and any additional properties specified by the application will replace individual defaults. Any default properties not overwritten will remain in effect. This has the benefit that only the properties you are interested in changing need to be specified, rather than a complete set.

    另一個需要注意的是init()方法可以被多次調(diào)用但并不會出現(xiàn)錯誤。但是,只有第一次調(diào)用init()方法才將使用配置屬性集來配置引擎,而其后對配置屬性的更改或者重新調(diào)用init()方法都會被忽略。Another thing to note is that the init() calls may be called more than once without harm in an application. However, the first call to any of the init() functions will configure the engine with the configuration properties set at that point, and any further configuration changes or init() calls will be ignored.

    最普通的初始化Velocity的方法會像是這樣:The most common approaches to initializing Velocity will be something like :

    1. 用類似于org/apache/velocity/runtime/defaults/velocity.properties文件的格式那樣將自己的需要的配置屬性的值寫入一個文件,或者放入一個java.util.Properties中,并且調(diào)用init(filename)或者init(Properties)方法。Setup the configuration values you wish to set in a file in the same format as org/apache/velocity/runtime/defaults/velocity.properties (the default set), or in a java.util.Properties, and then call either init( filename ) or init( Properties )
    2. 使用setProperty()方法獨立的設(shè)置配置屬性,并且調(diào)用init()方法。這個方法一般在比較高級的情況下------應(yīng)用擁有自己的配置管理系統(tǒng),比如應(yīng)用使用它自己生成的配置文件在運行時配置Velocity。Set the configuration values individually using setProperty() and then call init(). This method is generally used by more advanced applications that already have their own configuration management system - this allows the application so configure Velocity based upon values it generates at runtime, for example.

    一旦運行時被初始化,你可以做你想做的任何事情了,比如把模版合成并放入一個輸出流中,Velocity提供的工具類能幫你很簡單的完成這些任務(wù)。下面是一些該工具類的主要的方法的描述。Once the runtime is initialized, you can do with it what you wish.. This mostly revolves around rendering templates into an output stream, and the Velocity utility class allows you to do this easily. Currently, here are the methods and a brief description of what they do :

    • evaluate( Context context, Writer out, String logTag, String instring )
      evaluate( Context context, Writer writer, String logTag, InputStream instream )
      這些方法將使用你提供的上下文來解釋輸入流---String或InputStream對象存在,并放入一個輸出Writer中。這是一個很方便的用字符串替換標(biāo)識的方法,如果你堅持使用VTL'模版'-----即使這些'模版'是保存在數(shù)據(jù)庫中的,或者非文件形式的甚至直接是應(yīng)用生成的。These methods will render the input, in either the form of String or InputStream to an output Writer, using a Context that you provide. This is a very convenienient method to use for token replacement of strings, or if you keep 'templates' of VTL-containing content in a place like a database or other non-file storage, or simply generate such dynamically.
    • invokeVelocimacro( String vmName, String namespace, String params[], Context context, Writer writer )
      允許直接使用Velocity宏。這也能通過上面介紹的evaluate()方法達到。這里,你需要指定你想要執(zhí)行的宏的名字,創(chuàng)建一個傳遞給VM的參數(shù)的數(shù)組,一個帶有數(shù)據(jù)的上下文對象和一個輸出Writer。注意傳遞給VM的參數(shù)必須是在上下文中對應(yīng)的值得key值,而不是該宏真正要使用的參數(shù)值。就是說,宏真正得到的參數(shù)是通過傳入的key來從上下文中得到的值。這一個特性可能會在以后改變。Allows direct access to Velocimacros. This can also be accomplished via the evaluate() method above if you wish. Here you simply name the vm you wish to be called, create an array of args to the VM, a Context of data, and Writer for the output. Note that the VM args must be the 'keys' of the data objects in the Context, rather than literal data to be used as the arg. This will probably change.
    • mergeTemplate( String templateName, Context context, Writer writer )
      方便的調(diào)用Velocity的模版處理和合成服務(wù)的方法。該方法會處理并合成模版。更進一步的,該方法也會通過對文件資源加載器設(shè)置的屬性來加載模版,并且提供Velocity的文件和模版的緩存器。這是最有效的訪問模版的方法,除非你有特殊的需求,我們建議你使用該方法。Convenient access to the normal template handling and rendering services of Velocity. This method will take care of getting and rendering the template. It will take advantage of loading the template according to the properties setting for the file resource loader, and therefore provides the advantage of file and parsed template caching that Velocity offers. This is the most efficient way to access templates, and is recommended unless you have special needs.
    • boolean templateExists( String name )
      測試一個名字為name的模版文件是否能在當(dāng)前配置的資源加載器中找到。Determines if a template name is able to be found by the currently configured resource loaders.

    一旦我們了解了這些基本的助手方法,我們就能很容易的使用Velocity寫出Java程序了,如下面所示:Once we know about these basic helpers, it is easy to write Java program that uses Velocity. Here it is:

    import java.io.StringWriter;
    import org.apache.velocity.app.Velocity;
    import org.apache.velocity.VelocityContext;public class Example2
    {
    public static void main( String args[] )
    {
    /* first, we init the runtime engine. Defaults are fine. */Velocity.init();/* lets make a Context and put data into it */VelocityContext context = new VelocityContext();context.put("name", "Velocity");
    context.put("project", "Jakarta");/* lets render a template */StringWriter w = new StringWriter();Velocity.mergeTemplate("testtemplate.vm", context, w );
    System.out.println(" template : " + w );/* lets make our own string to render */String s = "We are using $project $name to render this.";
    w = new StringWriter();
    Velocity.evaluate( context, w, "mystring", s );
    System.out.println(" string : " + w );
    }

    當(dāng)我們運行這個程序,并且testtemplate.vm也在應(yīng)用的同一個目錄下(因為我們這里使用的是默認的資源加載器,會在當(dāng)前目錄下加載模版文件),我們的輸出應(yīng)該是:When we run this program, and have the template testtemplate.vm in the same directory as our program (because we used the default configuration properties, and the defaul place to load templates from is the current directory...), our output should be : template :

    Hi! This Velocity from the Jakarta project.

    string : We are using Jakarta Velocity to render this.

    testtemplate.vm的內(nèi)容是:where the template we used, testtemplate.vm, is

    Hi! This $name from the $project project.

    這就是在普通應(yīng)用中使用Velocity~注意我們沒有必要在一個應(yīng)用中同時mergeTemplate()和evaluate()方法。在這里同時使用它們是為了演示的需要。你可能只需要其中一個,但也要看你應(yīng)用的需求來選擇。That's all there is to it! Note that we didn't have to use both mergeTemplate() and evaluate() in our program. They are both included there for demonstration purposes. You will probably use only one of the methods, but depending on you application requirements, you are free to do what you wish.

    這段代碼和我們在指南開始時提到的基礎(chǔ)結(jié)構(gòu)有一些區(qū)別。第一,你創(chuàng)建了一個上下文對象并使用需要的數(shù)據(jù)填充,但在這個例子中,mergeTemlate()方法被使用了,mergeTemplate()方法為你處理了模版并且合成了輸出------使用的正是對底層的Runtime類的調(diào)用。在第二個例子中,你是通過一個String對象作為模版的,所以,代碼忽略了尋找模版的步驟,并且evaluate()調(diào)用底層方法為你合成了輸出。This appears to be a little different from the 'fundamental pattern' that was mentioned at the beginning of this guide, but it really is the same thing. First, you are making a context and filling it with the data needed. Where this examples differs is that in the part of the above example where mergeTemplate() is used, mergeTemplate() is doing the work of getting the template and merging it for you, using the lower-level calls in the Runtime class. In the second example, you are making your template dynamically via the String, so that is analgous to the 'choose template' part of the process, and the evaluate() method does the merging for you using lower level calls.

    So the example above sticks to the same simply pattern of using the Velocity template engine, but the utility functions do some of the repeated drudge work, or allow you other options for your template content other than template files.

    異常Exceptions

    在解析和合成的過程中,會有三種異常可能被拋出。這些是除了IO錯誤之外的錯誤,在org.apache.vleocity.exception包中可以找到它們:There are three exceptions that Velocity will throw during the parse / merge cycle. This are additional to the exceptions that will come from IO problems, etc. They are found in the package org.apache.velocity.exception and are:

    1. ResourceNotFoundException
      當(dāng)資源管理系統(tǒng)不能找到一個請求的資源(模版)的時候拋出。Thrown when the resource managment system cannot find a resource (template) that was requested.
    2. ParseErrorException
      當(dāng)在解析一個資源(模版)發(fā)現(xiàn)語法錯誤的時候拋出。Thrown when a VTL syntax error is found when parsing a resource (template).
    3. MethodInvocationException
      當(dāng)在合成時期,上下文中一個對象的方法執(zhí)行期間拋出異常時拋出。該出錯方法拋出的錯誤將會被包裝并傳遞給應(yīng)用。這要求你在運行時處理自己的對象拋出的錯誤。Thrown when a method of object in the context thrown an exception during render time. This exception wraps the thrown exception and propogates it to the application. This allows you to handle problems in your own objects at runtime.

    一旦以上的情況發(fā)生,一個錯誤信息就會被放入運行時日志中。更多信息請參見Javadoc API文檔。In each case, a message is put into the runtime log. For more information, see the Javadoc API documentation.

    其他細節(jié)Miscellaneous Details

    盡管上面的例子使用的是默認的配置,但是要使用自定義的配置也是很容易的事情。你需要做的就是創(chuàng)建一個屬性文件,并將該文件的路徑名通過init(String)方法或者通過創(chuàng)建一個自定義屬性名/值的java.util.Properties對象并調(diào)用init(Properties)方法既可以了。后者更為方便,因為你既可以通過使用load()方法從某個屬性文件中加載屬性,也可以在運行時動態(tài)的從你的應(yīng)用或者框架的配置文件中得到。這給了你將關(guān)于應(yīng)用的所有屬性都配置在一個文件中的靈活性。While the above example used the default properties, setting your own properties is very simple. All you have to do is make a properties file somewhere and pass the name of that file to the init(String) method of the Velocity utility class, or make a java.util.Properties object, add the desired properties and values, and pass that to the init(Properties) method. The latter method is convenient, because you can either fill it directly from a separate properties file via the load() method, or even better, you can fill it dynamically from your own application / framework's property set at runtime. This gives you the freedom to combine all of the properties for your app into one properties file.

    如果我們想使用一個不同的文件夾來存放模版文件,我們就可以象這樣來加載它們:If we wanted to use a different directory than the current directory to load our template from, we could do something like this :

    ...import java.util.Properties;
    ...public static void main( String args[] )
    {
    /* first, we init the runtime engine. */Properties p = new Properties();
    p.setProperty("file.resource.loader.path", "/opt/templates");
    Velocity.init( p );/* lets make a Context and put data into it */...

    現(xiàn)在,假設(shè)你有一個/opt/templates文件夾,并且有一個叫做testtemplate.vm的模版文件在里面,那么一切都將正常工作。如果你這樣做后發(fā)生了一些錯誤,那么請確認velocity.log中的記錄來得到更多的信息------錯誤消息能很快地確定哪里出錯了。And, assuming you have a directory /opt/templates and the template testtemplate.vm is in there, then things would work just fine. If you try this and have a problem, be sure to look at the velocity.log for information - the error messages are pretty good for figuring out what is wrong. 應(yīng)用屬性

    Application Attributes

    應(yīng)用屬性是名/值對,在RuntimeInstance中被訪問。Application Attributes are name-value pairs that can be associated with a RuntimeInstance (either via the VelocityEngine or the Velocity singleton) and accessed from any part of the Velocity engine that has access to the RuntimeInstance.

    這個特性是為了那些需要在應(yīng)用層和自定義的Velocity引擎之間聯(lián)系的情況而設(shè)計的,這些聯(lián)系包括資源加載器,日志記錄器和資源管理器等等。This feature was designed for applications that need to communicate between the application layer and custom parts of the Velocity engine, such as loggers, resource loaders, resource managers, etc.

    應(yīng)用屬性API很簡單,從應(yīng)用層來看,在VelocityEngine和Velocity類中都有一個方法:The Application Attribute API is very simple. From the application layer, there is a method of the VelocityEngine and the Velocity classes : public void setApplicationAttribute( Object key, Object value );

    through which an application can store on Object under an application (or internal component) specified key. There are no restrictions on the key or the value. The value for a key may be set at any time - it is not required that this be set before init() is called.

    Internal components can access the key-value pairs if they have access to the object via the RuntimeServices interface, using the method public Object getApplicationAttribute( Object key );

    Note that internal components cannot set the value of the key, just get it. if the internal component must communicate information to the application layer, it must do so via the Object passed as the value.

    EventCartridge and Event Handlers

    從Velocity1.1開始,一個結(jié)構(gòu)良好的事件處理系統(tǒng)被添加到Velocity中。EventCartridge是一個你用來注冊你的事件處理器的類,并且在需要的時候,這個類扮演了一個Velocity引擎將和事件處理器之間聯(lián)系的中轉(zhuǎn)代理角色。目前,有三個事件可以被處理,他們都在org.apache.velocity.app.event包中。Starting in version 1.1, a fine-grain event handling system was added to Velocity. The EventCartridge is a class in which you register your event handlers, and then the EventCartridge acts as the delivery agent from which the Velocity engine will access the event handlers at merge time if needed. Currently, there are 3 events that can be handled, and all are found in the org.apache.velocity.app.event package.

    org.apache.velocity.app.event.NullSetEventHandler 當(dāng)一個#set()導(dǎo)致了一個空的賦值,一般情況下這會被日志記錄。

    NullSetEventHandler允許你禁止在這種情況下記錄日志。When a #set() results in a null assignment, this is normally logged.

    The NullSetEventHandler allows you to 'veto' the logging of this condition.

    public interface NullSetEventHandler extends EventHandler
    {
    public boolean shouldLogOnNullSet( String lhs, String rhs );
    }
    org.apache.velocity.app.event.ReferenceInsertionEventHandler

    ReferenceInsertionEventHandler 允許程序員攔截每一個將要寫入輸出流中的的引用的值,并修改輸出流。A ReferenceInsertionEventHandler allows the developer to intercept each write of a reference ($foo) value to the output stream and modify that output.

    public interface ReferenceInsertionEventHandler extends EventHandler
    {
    public Object referenceInsert( String reference, Object value );
    }
    org.apache.velocity.app.event.MethodExceptionEventHandler 當(dāng)一個用戶定義的方法拋出了異常時,該事件處理器被觸發(fā),方法中帶有拋出異常的類,拋出異常的方法名,和拋出的異常。該方法允許返回一個合法的對象,并且返回的對象將被合并到輸出流中,同時,你也能將傳入的異常重新拋出或者包裝后拋出,這些方法將被包裝成一個MethodInvocationException并且返回給用戶。When a user-supplied method throws an exception, the MethodExceptionEventHandler is invoked with the Class, method name and thrown Exception. The handler can either return a valid Object to be used as the return value of the method call, or throw the passed-in or new Exception, which will be wrapped and propogated to the user as a MethodInvocationException

    public interface MethodExceptionEventHandler extends EventHandler
    {
     public Object methodException( Class claz, String method, Exception e ) throws Exception;
    }

    使用EventCartridge Using the EventCartridge

    使用EventCartridge也很直接。下面的這個簡化了的例子是從org.apache.velocity.test.misc.Test中取出的。 the EventCartridge is fairly straightforward. The following abbreviated example was taken from org.apache.velocity.test.misc.Test. ...

    import org.apache.velocity.app.event.EventCartridge;
    import org.apache.velocity.app.event.ReferenceInsertionEventHandler;
    import org.apache.velocity.app.event.MethodExceptionEventHandler;
    import org.apache.velocity.app.event.NullSetEventHandler;...public class Test implements ReferenceInsertionEventHandler,
    NullSetEventHandler,
    MethodExceptionEventHandler
    {
    public void myTest()
    {
    ..../*now, it's assumed that Test implements the correct methods tosupport the event handler interfaces. So to use them, firstmake a new cartridge
    */
    EventCartridge ec = new EventCartridge();/*then register this class as it contains the handlers
    */
    ec.addEventHandler(this);/*and then finally let it attach itself to the context
    */
    ec.attachToContext( context );/*now merge your template with the context as you normallydo
    */....
    }/*and now the implementations of the event handlers
    */
    public Object referenceInsert( String reference, Object value )
    {
    /* do something with it */
    return value;
    }public boolean shouldLogOnNullSet( String lhs, String rhs )
    {
    if ( /* whatever rule */ )
    return false;return true;
    }public Object methodException( Class claz, String method, Exception e )
    throws Exception
    {
    if ( /* whatever rule */ )
    return "I should have thrown";throw e;
    }
    }

    Velocity Configuration Keys and Values

    Velocity運行時配置是被一組配置關(guān)鍵字控制的。一般來說,這些關(guān)鍵字都和一個String,或者一個逗號分隔的String值對應(yīng)。Velocity's runtime configuration is controlled by a set of configuration keys listed below. Generally, these keys will have values that consist of either a String, or a comma-separated list of Strings, referred to as a CSV for comma-separated values.

    在Velocity的jar文件中的/src/java/org/apache/runtime/defaults/velocity.defaults文件中,定義了一組默認值,Velocity把這組默認值作為基礎(chǔ)配置。這樣做確保了Velocity在啟動的時候總是含有正確的配置值,雖然這些值不一定都是你希望的。There is a set of default values contained in Velocity's jar, found in /src/java/org/apache/velocity/runtime/defaults/velocity.defaults, that Velocity uses as it's configuration baseline. This ensures that Velocity will always have a 'correct' value for it's configuration keys at startup, although it may not be what you want.

    在使用init()方法之前自定義的值都能代替默認值。因此你只需要使用你需要改變的關(guān)鍵字和值來配置Velocity,而不需要包含其他的。Any values specified before init() time will replace the default values. Therefore, you only have to configure velocity with the values for the keys that you need to change, and not worry about the rest. Further, as we add more features and configuration capability, you don't have to change your configuration files to suit - the Velocity engine will always have default values.

    請參見Using Velocity In General Applications 小節(jié),得到關(guān)于配置API的討論。Please sees the section above Using Velocity In General Applications for discussion on the configuration API.

    下面列出了控制Velocity行為的關(guān)鍵字,通過不同的種類來組織的,在每一個關(guān)鍵字介紹之后都給出了目前的默認值。Below are listed the configuration keys that control Velocity's behavior. Organized by category, each key is listed with it's current default value to the right of the '=' sign.

    運行時日志Runtime Log

    runtime.log = velocity.log
    用于記錄錯誤,警告,信息的日志文件的完整路徑和名字。該路徑不是絕對路徑,則相對于當(dāng)前路徑。Full path and name of log file for error, warning, and informational messages. The location, if not absolute, is relative to the 'current directory'.

    runtime.log.logsystem
    該屬性沒有默認值。他是用來提供給Velocity一個實現(xiàn)了org.apache.velocity.runtime.log.LogSystem接口的日志記錄類,該類允許Velocity日志信息和你的其他應(yīng)用的日志信息結(jié)合起來。請參看Configuring the Log System 來得到更多信息。This property has no default value. It is used to give Velocity an instantiated instance of a logging class that supports the interface org.apache.velocity.runtime.log.LogSystem., which allows the combination of Velocity log messages with your other application log messages. Please see the section Configuring the Log System for more information.

    runtime.log.logsystem.class = org.apache.velocity.runtime.log.AvalonLogSystem
    用來作為Velocity日志系統(tǒng)的類。Class to be used for the Velocity-instantiated log system.

    runtime.log.error.stacktrace = false
    runtime.log.warn.stacktrace = false
    runtime.log.info.stacktrace = false
    為這三種種類的錯誤打開棧信息輸出。這些信息會導(dǎo)致大量的日志記錄工作。Turns on stacktracing for the three error categories. These produce a large amount of log output.

    runtime.log.invalid.references = true
    該屬性關(guān)掉了當(dāng)一個引用無效時的日志記錄。在產(chǎn)品中因該關(guān)掉,而在調(diào)式的時候,這是很有用的信息。Property to turn off the log output when a reference isn't valid. Good thing to turn of in production, but very valuable for debugging.

    runtime.log.logsystem.avalon.logger =name
    允許用戶自定義一個在Avalon系統(tǒng)中存在的日志記錄器的名字而不需要用一個LogSystem接口包裝。注意,你必須同時也定義好runtime.log.logsystem.class=org.apache.velocity.runtime.log.AvalonLogSystem作為默認的日志記錄器也需要改變。因為這樣并不保證Avalon日志系統(tǒng)仍然是默認的日志系統(tǒng)。Allows user to specify an existing logger name in the Avalon hierarchy without having to wrap with a LogSystem interface. Note: You must also specify runtime.log.logsystem.class = org.apache.velocity.runtime.log.AvalonLogSystem as the default logsystem may change. There is no guarantee that the Avalon log system will remain the default log system.

    編碼格式Character Encoding

    input.encoding = ISO-8859-1
    輸入(模版)的編碼格式。使用該屬性,你能改變你模版中的字符編碼,比如utf-8。Character encoding for input (templates). Using this, you can use alternative encoding for your templates, such as UTF-8.

    output.encoding = ISO-8859-1
    VelocityServlet和Anakia中的輸出流的編碼格式。Character encoding for output streams from the VelocityServlet and Anakia.

    #foreach() Directive

    directive.foreach.counter.name = velocityCount
    使用#foreach()指示符時,作為上下文中遍歷計數(shù)器的對象的名字。在模版中可以使用象$velocityCount來引用計數(shù)器。Used in the #foreach() directive, defines the string to be used as the context key for the loop count. A template would access the loop count as $velocityCount.

    directive.foreach.counter.initial.value = 1
    在#foreach中遍歷計數(shù)器的起始值。Default starting value for the loop counter reference in a #foreach() loop.

    #include() and #parse() Directive

    directive.include.output.errormsg.start =
    directive.include.output.errormsg.end =

    定義一個#include()指示符導(dǎo)致的輸入流錯誤信息的開始標(biāo)志和結(jié)束標(biāo)志,如果開始和結(jié)束標(biāo)志都定義了,比如starttag和endtag為對應(yīng)的值,那么一個錯誤的信息將會以格式starttag msg endtag放入輸出流中。只有開始和結(jié)束標(biāo)志都定義了,消息才會被放入輸出流中。Defines the beginning and ending tags for an in-stream error message in the case of a problem with the #include() directive. If both the .start and .end tags are defined, an error message will be output to the stream, of the form '.start msg .end' where .start and .end refer to the property values. Output to the render stream will only occur if both the .start and .end (next) tag are defined.

    directive.parse.maxdepth = 10
    定義一個模版允許的解析深度。一個模版可能會#parse另一個也有#parse的模版。該值防止了#parse的死循環(huán)。Defines the allowable parse depth for a template. A template may #parse() another template which itself may have a #parse() directive. This value prevents runaway #parse() recursion.

    資源管理Resource Management

    resource.manager.logwhenfound = true
    用來控制是否在資源管理器中將"found"日志信息打開。當(dāng)一個資源被第一次找到,該資源的名字和類名將被記錄在日志文件中。Switch to control logging of 'found' messages from resource manager. When a resource is found for the first time, the resource name and classname of the loader that found it will be noted in the runtime log.

    resource.loader = <name> (default = File)
    多值的關(guān)鍵字,允許使用CSV作為值。Multi-valued key. Will accept CSV for value. 配置要使用的資源加載器的名字。該被配置的名字會繼續(xù)用來配置對應(yīng)資源管理器的特定屬性。注意,作為一個多值的關(guān)鍵字,你能傳入一個了類似"file,class"(不需要引號),表明下面將要為兩個加載器作配置。Pulic name of a resource loader to be used. This public name will then be used in the specification of the specific properties for that resource loader. Note that as a multi-valued key, it's possible to pass a value like "file, class" (sans quotes), indicating that following will be configuration values for two loaders.

    <name>.loader.description = Velocity File Resource Loader
    一個特定的資源加載器的描述。Description string for the given loader.

    <name>.resource.loader.class = org.apache.velocity.runtime.resource.loader.FileResourceLoader
    加載器實現(xiàn)類的名字。默認的加載器是文件加載器。Name of implementation class for the loader. The default loader is the file loader.

    <name>.resource.loader.path = .
    多值關(guān)鍵字,允許使用CSV作為值。Multi-valued key. Will accept CSV for value. 加載器加載模版的根目錄。模版能放在該目錄的任何子目錄下。比如homesite/index.vm。該配置目前作用于FileResourceLoader和JarResourceLoader。Root(s) from which the loader loads templates. Templates may live in subdirectories of this root. ex. homesite/index.vm This configuration key applies currently to the FileResourceLoader and JarResourceLoader.

    <name>.resource.loader.cache = false
    在加載器中控制緩存。默認為false,為的是使開發(fā)和調(diào)試比較簡單。該配置應(yīng)該在產(chǎn)品中設(shè)置為true。當(dāng)modifictionCheckInterval屬性被設(shè)置,這允許相當(dāng)有效的緩存。Controls caching of the templates in the loader. Default is false, to make life easy for development and debugging. This should be set to true for production deployment. When 'true', the modificationCheckInterval property applies. This allows for the efficiency of caching, with the convenience of controlled reloads - useful in a hosted or ISP environment where templates can be modifed frequently and bouncing the application or servlet engine is not desired or permitted.

    <name>.resource.loader.modificationCheckInterval = 2
    當(dāng)緩存開啟時,該選項確定了緩存中兩次修改檢查的間隔時間。當(dāng)選項是一個大于0的數(shù)值時,該屬性規(guī)定了兩次檢查模版是否被修改的間隔時間。如果模版在上一次檢查之后被修改,該模版將會被重新加載并重新解析,否則沒有任何動作。如果該值小于0,不會執(zhí)行任何修改檢查。假設(shè)屬性cache 為true,一旦模版被加載并解析后,直到應(yīng)用或者servlet引擎重起,模版的任何改動都不會被響應(yīng)。This is the number of seconds between modification checks when caching is turned on. When this is an integer > 0, this represents the number of seconds between checks to see if the template was modified. If the template has been modified since last check, then it is reloaded and reparsed. Otherwise nothing is done. When <= 0, no modification checks will take place, and assuming that the property cache (above) is true, once a template is loaded and parsed the first time it is used, it will not be checked or reloaded after that until the application or servlet engine is restarted.

    作為一個演示,這里是一個演示了怎樣配置FileResourceLoader的例子:To illustrate, here is an example taken right from the default Velocity properties, showing how setting up the FileResourceLoader is managed resource.loader = file

    file.resource.loader.description = Velocity File Resource Loader
    file.resource.loader.class =
    org.apache.velocity.runtime.resource.loader.FileResourceLoader
    file.resource.loader.path = .
    file.resource.loader.cache = false
    file.resource.loader.modificationCheckInterval = 2

    Velocity宏Velocimacro

    velocimacro.library = VM_global_library.vm
    多值的關(guān)鍵字,允許使用CSV作為值。Multi-valued key. Will accept CSV for value. 當(dāng)Velocity運行時引擎開始的時候,會加載這些宏的文件名到Velocity宏庫中。所有的模版都能直接使用這些Velocity宏。這些文件路徑都相對于文件加載器根路徑。Filename(s) of Velocimacro library to be loaded when the Velocity Runtime engine starts. These Velocimacros are accessable to all templates. The file is assumed to be relative to the root of the file loader resource path.

    velocimacro.permissions.allow.inline = true
    通過在一個模版中使用#macro()指示符來定義宏是否允許的。默認值為true,意味著所有的模版都能定義并使用新的宏。注意,依賴于其他的屬性,#macro()語句可以覆蓋全局定義。Determines of the definition of new Velocimacros via the #macro() directive in templates is allowed. The default value is true, meaning any template can define and use new Velocimacros. Note that depending on other properties, those #macro() statements can replace global definitions.

    velocimacro.permissions.allow.inline.to.replace.global = false
    控制在模版中定義的宏是否能覆蓋在啟動時加載到Velocity宏庫中的宏。Controls if a Velocimacro defind 'inline' in a template can replace a Velocimacro defined in a library loaded at startup.

    velocimacro.permissions.allow.inline.local.scope = false
    控制私有定義的宏的作用空間。當(dāng)該值為true的時候,在一個模版中定義的宏只能在該模版中使用。這意味著Velocity只能通過在啟動時把宏加入到宏庫中來實現(xiàn)共享,同時也意味著模版之間的宏不會互相沖突。該屬性允許了一種技巧,即可以在全局或本地的宏庫中定義一組缺省的宏,各個模版能通過覆蓋來實現(xiàn)自己的方法,因為當(dāng)該屬性為true,會在全局宏庫之前先搜索在本模版中的宏,因此,實現(xiàn)了這種覆蓋機制。Controls 'private' templates namespaces for Velocimacros. When true, a #macro() directive in a template creates a Velocimacro that is accessable only from the defining template. This means that Velocimacros cannot be shared unless they are in the global or local library loaded at startup. (See above.) It also means that templates cannot interfere with each other. This property also allows a technique where there is a 'default' Velocimacro definition in the global or local library, and a template can 'override' the implementation for use within that template. This occurrs because when this property is true, the template's namespace is searched for a Velocimacro before the global namespace, therefore allowing the override mechanism.

    velocimacro.context.localscope = false
    控制在宏中的引用是否能改變上下文,或者只能改變該宏所在的本地范圍。Controls whether reference access (set/get) within a Velocimacro will change the context, or be of local scope in that Velocimacro.

    velocimacro.library.autoreload = false
    控制宏庫的自動重加載。當(dāng)該屬性為true時,就會觸發(fā)對宏庫的代碼的改變的檢查,并在需要的時候重新加載宏庫。這允許你修改和測試你的宏庫而不需要每次都手動的重起應(yīng)用或者servlet容器。該選項只有在緩存被關(guān)閉的時候才有用(比如設(shè)置file.resource.loader.cache=false)。該特性主要使用在開發(fā)階段,不適合使用在產(chǎn)品中。Controls Velocimacro library autoloading. When set to true the source Velocimacro library for an invoked Velocimacro will be checked for changes, and reloaded if necessary. This allows you to change and test Velocimacro libraries without having to restart your application or servlet container, just like you can with regular templates. This mode only works when caching is off in the resource loaders (e.g. file.resource.loader.cache = false ). This feature is intended for development, not for production.

    String Interpolation

    runtime.interpolate.string.literals = true
    Controls interpolation mechanism of VTL String Literals. Note that a VTL StringLiteral is specifically a string using double quotes that is used in a #set() statement, a method call of a reference, a parameter to a VM, or as an argument to a VTL directive in general. See the VTL reference for further information.

    運行時配置Runtime Configuration

    parser.pool.size = 20
    該屬性控制在Velocity啟動時需要創(chuàng)建并放在緩存池中的解析器的個數(shù)。默認的20個應(yīng)該能滿足絕大多數(shù)的應(yīng)用的需要了。當(dāng)Velocity沒有了足夠的解析器的時候,將會在日志中記錄,并動態(tài)的創(chuàng)建新的來使用。注意,這時候創(chuàng)建的解析器就不會再被放入緩存池中了,這時候的解析速度就比較常態(tài)慢了,但這中狀態(tài)也應(yīng)該被視為一個異常的狀態(tài),如果你在日志中發(fā)現(xiàn)了這種信息,請增加該值。This property sets the number of parsers that Velocity will create at startup and keep in a pool. The default of 20 parsers should be more than enough for most uses. In the event that Velocity does run out of parsers, it will indicate so in the log, and dynamically create them as needed. Note that they will not be added to the pool. This is a slow operation compared to the normal parser pooling, but this is considered an exceptional condition. If you see a log message, please increment this property.

    配置日志系統(tǒng)Configuring the Log System

    Velocity提供了幾個優(yōu)秀的日志特點來滿足簡單性和靈活性。不需要任何的配置,Velocity就會建立一個基于文本記錄的日志記錄器,并且將所有的日志信息記錄到一個叫做velocity.log的文件中,該文件保存在當(dāng)前目錄下。更高級的用戶,可以將你目前應(yīng)用使用的日志記錄設(shè)施和Velocity結(jié)合起來,使Velocity將日志信息發(fā)送到你目前的日志中。Velocity has a few nice logging features to allow both simplicity and flexibility. Without any extra configuration, Velocity will setup a file-based logger that will output all logging messages to a file called velocity.log in the 'current directory' where Velocity was initialized. For more advanced users, you may integrate your current logging facilities with Velocity to have all log messages sent to your logger.

    從1.3版本開始,Velocity會自動地使用Jakarta Avalon Logkit 或者Jakarta Log4j 日志記錄。在類路徑下發(fā)現(xiàn)了這兩個日志框架之一,它就使用哪個。他首先會嘗試使用Logkit,如果沒有發(fā)現(xiàn)Logkit,那么它在嘗試使用Log4j。Starting with version 1.3, Velocity will automatically use either the Jakarta Avalon Logkit logger, or the Jakarta Log4j logger. It will do so by using whatever it finds in the current classpath, starting first with Logkit. If Logkit isn't found, it tries Log4j.

    利用這個特點,只需要不包含任何依賴庫的Velocity包,并將你需要的日志框架------logkit或者log4j放在類路徑下就可以了。To utilize this feature, simply use the 'non-dependency' Velocity jar (because Logkit is baked into the jar with dependencies) and place either the logkit or log4j jar in your classpath.

    總的來說,你有下面一個關(guān)于日志的選項。In general, you have the following logging options :

    • 默認的配置Default Configuration
      在缺省配置下,Velocity將會在當(dāng)前目錄下創(chuàng)建一個基于文本的日志記錄器。By default, Velocity will create a file-based logger in the current directory. See the note above regarding automatic detection of Logkit or Log4j to use as the default logging system.
    • 使用現(xiàn)存的Log4j。Existing Log4j Category
      從1.3版本開始,Velocity將會把它的日志輸出記錄到應(yīng)用中一個存在的Log4j框架中。要使用該特性,你需要:Starting with version 1.3, Velocity will log it's output to an existing Log4j Category setup elsewhere in the application. To use this feature you must
      1. 確定Log4j的jar文件在你的類路徑下。Make sure that the Log4j jar is in your classpath. (You would do this anyway since you are using Log4j in the application using Velocity.)
      2. 配置Velocity使用SimpleLog4jLogSystem類。Configure Velocity to use the SimpleLog4jLogSystem class.
      3. 通過配置runtime.log.logsystem.log4j.category屬性來確定一個存在的Category的名字。Specify the name of the existing Category to use via the 'runtime.log.logsystem.log4j.category' property.

    這種方法不能在老版本中的Log4JLogSystem類中使用。如何用代碼來做到這些,請參見下面的例子。This approach replaces and deprecates the older Log4JLogSystem class. To see how this is done in code, see the example below.

    • 自定義的獨立的日志記錄器Custom Standalone Logger
      你可以創(chuàng)建一個自定義的日志記錄類,一般情況下,你必須實現(xiàn)org.apache.velocity.runtime.log.LogSystem接口,并配置runtime.log.logsystem.class屬性來指向你自定義的類名,在初始化的時候Velocity將創(chuàng)建一個該類的實例。同樣,你需要為該名稱的日志記錄器配置其他的屬性。請參見 Velocity helper class 和configuration keys and values. 來得到更詳細信息。請注意,由于疏忽的原因,在1.2版本中,org.apache.velocity.runtime.log.LogSystem接口被修改了以支持分離的實例末拌。如果你有一個自定義的適用于1.2以前版本的日志記錄器,你需要再添加一個init(RuntimeServices)方法。You can create a custom logging class - you simply must implement the interface org.apache.velocity.runtime.log.LogSystem and then simply set the configuration property runtime.log.logsystem.class with the classname, and Velocity will create an instance of that class at init time. You may specify the classname as you specify any other properties. See the information on the Velocity helper class as well as the configuration keys and values. Please note that through oversight, the interface to org.apache.velocity.runtime.log.LogSystem was changed in v1.2 to support the separable instances of the Velocity runtime. If you have an exisiting pre v1.2 custom logger that is going to be instantiated by the Velocity LogManager, you must add the init( RuntimeServices ) method.
    • 整合日志系統(tǒng)Integrated Logging
      你可以將Velocity日志系統(tǒng)整合進你現(xiàn)有應(yīng)用已經(jīng)在使用的日志系統(tǒng)中,只需要實現(xiàn)org.apache.velocity.runtime.log.LogSystem接口。然后,通過配置runtime.log.logsystem屬性在Velocity引擎初始化之前傳入一你現(xiàn)有的日志類,Velocity就會將日志信息記錄到你的應(yīng)用中的日志中了。請參見 Velocity helper class 和configuration keys and values. 來得到更詳細信息。You can integrate Velocity's logging capabilities with your applications existing logging system, simply by implementing the org.apache.velocity.runtime.log.LogSystem interface. Then, pass an instance of your logging class to Velocity via the runtime.log.logsystem configuration key before initializing the Velocity engine, and Velocity will log messages to your applications logger. See the information on the Velocity helper class as well as the configuration keys and values.

    使用現(xiàn)有的Log4jUsing Log4j With Existing Category
    下面是一個演示怎樣配置Velocity使其記錄日志到一個存在的Log4j中。Here is an example of how to configure Velocity to log to an existing Log4j Category. import org.apache.velocity.app.VelocityEngine;

    import org.apache.velocity.runtime.RuntimeConstants;import org.apache.log4j.Category;
    import org.apache.log4j.BasicConfigurator;public class Log4jCategoryExample{ public static String CATEGORY_NAME = "velexample"; public static void main( String args\[\] ) throws Exception { /* * configure log4j to log to console */ BasicConfigurator.configure(); Category log = Category.getInstance( CATEGORY_NAME ); log.info("Hello from Log4jCategoryExample - ready to start velocity"); /* * now create a new VelocityEngine instance, and * configure it to use the category */ VelocityEngine ve = new VelocityEngine(); ve.setProperty( RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, "org.apache.velocity.runtime.log.SimpleLog4JLogSystem" ); ve.setProperty("runtime.log.logsystem.log4j.category", CATEGORY_NAME); ve.init(); log.info("this should follow the initialization output from velocity"); }}

    注意該例子可以在examples/logger_example中找到。Note that the above example can be found in examples/logger_example.

    一個自定義日志記錄器的例子Simple Example of a Custom Logger

    下面是一個演示如何使用一個你自己的日志記錄器來作日志的例子。注意我們并沒有使用來類的名字,而是傳遞了一個該類的實例。要做到這點,需要繼承LogSystem接口。Here is an example of how to use an instantiation of your class that implements Velocity's logging system as the logger. Note that we are not passing the name of the class to use, but rather a living, existing instantiation of the class to be used. All that is required is that it support the LogSystem interface.

    import org.apache.velocity.runtime.log.LogSystem;
    import org.apache.velocity.runtime.RuntimeServices;
    ...
    public class MyClass implements LogSystem
    {
    ...
    public MyClass()
    {
    ...
    try
    {
    /* * register this class as a logger */
    Velocity.setProperty(Velocity.RUNTIME_LOG_LOGSYSTEM, this );
    Velocity.init();
    } catch (Exception e)
    {
    /* * do something */
    }
    }
    /** * This init() will be invoked once by the LogManager * to give you current RuntimeServices intance */
    public void init( RuntimeServices rsvc )
    {
    // do nothing
    }
    /** * This is the method that you implement for Velocity to call * with log messages. */
    public void logVelocityMessage(int level, String message)
    {
    /* do something useful */
    }
    ...
    }

    Configuring Resource Loaders

    資源加載器Resource Loaders

    Velocity的一個重要的基礎(chǔ)設(shè)施就是資源管理系統(tǒng)和資源加載器。他們指向的是資源,而不只是模版,因為資源管理系統(tǒng)不光能處理模版,也能處理非模版的資源,比如在模版中使用#incude()指示符加載的東西。One of the fundamental and important parts about Velocity is the resource management system and the resource loaders. They are referred to as 'resources' here rather than 'templates' because the resource management system will also handle non-template reasources, specifically things that are loaded via the #include() directive.

    資源加載器系統(tǒng)是很靈活的,允許一個或者多個資源加載器同時工作,這允許在配置和資源管理上有很大的靈活性,并允許你為自己的需求編寫自定義的資源加載器。The resource loader system if very flexible, allowing one or more resource loaders to be in operation at the same time. This allows tremendous flexibility in configuration and resource managment, and futher allows you to write your own resource loaders for your special needs.

    目前,Velocity中有4種資源加載器,都在下面描述。注意,在給出的配置實例中,一個加載器的名字會出現(xiàn)(比如file.resource.loader.path中的"file"),這個名字在你的配置文件中可能不會起作用,請閱讀resource configuration properties 小節(jié)來理解該系統(tǒng)是怎樣工作的。同時,下面的這些加載器都是在org.apache.velocity.runtime.resource.loader包中。There are currently four kinds of resource loaders that are included with Velocity, each described below. Note that in the example configuration properties given, a common name for the loader is shown (ex.'file' in file.resource.loader.path). This 'common name' may not work for your configuration. Please read the section on resource configuration properties to understand how this system works. Also, each of these loaders is located in the package org.apache.velocity.runtime.resource.loader.

    • FileResourceLoader : 該加載器從文件系統(tǒng)中加載資源。他的配置屬性包括:This loader gets resources from the filesystem. It's configuration properties include :
      • file.resource.loader.path = <path to root of templates>
      • file.resource.loader.cache = true/false
      • file.resource.loader.modificationCheckInterval = <seconds between checks>

    這是默認的加載器,并且從當(dāng)前文件夾加載資源(模版)。當(dāng)Velocity使用于Servlet中時,這會成為一個問題,因為你一定不希望模版放在你servlet引擎的根目錄下。請參見 developing servlets with Velocity 得到更多信息。This is the default loader, and is configured, by default to get templates from the 'current directory'. In the case of using Velocity with servlets, this can be a problem as you don't want to have to keep your templates in the directory from which you start your servlet engine. Please see the section on developing servlets with Velocity for more information.

    • JarResourceLoader : 該資源加載器從一個指定的jar文件中加載資源。他的工作狀態(tài)和FileResourceLoader非常相似,除非你認為將你的模版資源打包如jar文件中是很方便的。他們的配置屬性也是一樣的,除了jar.resource.loader.path。該屬性確定了你把所有的需要加載的資源的jar文件都放入的絕對路徑。要配置該屬性,需要使用標(biāo)準(zhǔn)的java.net.JarURLConnection中的JAR URL語法。This loader gets resource from specific jar files. It is very similar to the FileResourceLoader, except that you have the convenience of bundling your templates into jars. The properties are identical, except for jar.resource.loader.path, where you provide the full location of the jar(s) you wish to load resources from. To specify a jar for the loader.path you use the standard JAR URL syntax of java.net.JarURLConnection.
    • ClasspathResourceLoader : 該加載器從類路徑中加載資源。簡單的說,該加載器會加載放置在類路徑中的模版資源(比如在某個jar中)。在使用符合Servlet2.2或之后的版本的容器時,這是一個比較簡單的機制。Tomcat就是這樣一種容器。要更有效的使用該加載器,你只需要把所有的模版資源打包為jar文件,并放入你web應(yīng)用的web-inf文件夾中即可。沒有任何的配置選項需要考慮,也沒有了關(guān)于相對路徑絕對路徑的考慮。請再次注意,ClasspathResourceLoader不光適用于servlet應(yīng)用中,也同樣適用于其他任何的應(yīng)用環(huán)境。This loader gets resources from the classloader. In general, this means that the ClasspathResourceLoader will load templates placed in the classpath (in jars, for example) While the classpath is a source of great pain and suffering in general, it is a very useful mechanism when working on a Servlet Spec 2.2 (or newer) compliant servlet runner. Tomcat is an example of such. To use this loader effectively, all you must do is jar your templates, and put that jar into the WEB-INF/lib directory of your webapp. There are no configuration options to worry about, nor is the absolute vs. relative path an issue, as it is with Jar and File resource loaders. Again, please note that the ClasspathResourceLoader is not only for use with a servlet container, but can be used in any application context.
    • DataSourceResourceLoader : 在加載器會從一個DataSource中加載資源,比如一個數(shù)據(jù)庫中。該加載器不是一個標(biāo)準(zhǔn)的加載器,因為使用它需要J2EE的支持。要構(gòu)建該加載器,需要下載J2EE的分發(fā)包,把j2ee.jar放入build/lib文件夾中,并使用jar-j2ee構(gòu)建任務(wù)來構(gòu)建一個新的Velocity jar文件。要得到關(guān)于該加載器的更多的信息,請參見Javadoc中關(guān)于org.apache.velocity.resource.loader.DataSourceResourceLoader類的文檔。This loader will load resources from a DataSource such as a database. This loader is not built as part of the standard build as it requires J2EE support. To build this loader, please download the J2EE distribution, move the j2ee.jar into the build/lib directory, and then build the new velocity jar with the jar-j2ee build target. For more information on this loader, please see the javadoc for the class org.apache.velocity.runtime.resource.loader.DataSourceResourceLoader.

    配置示例 Configuration Examples

    為Velocity配置資源加載器是很直接的事,所有控制的屬性都在 resource configuration 小節(jié)列出。Configuring the resource loaders for Velocity is straightforward. The properties that control the are listed in the resource configuration section, for further reference.

    在Velocity中配置資源加載器的第一件事情就是聲明他們的名字。使用resource.loader屬性來列出一個或者多個配置器的名稱。你可以使用任何你想要的名字------該名字用于接下來配置該加載器的屬性。The first step in configuring one or more resource loaders is do 'declare' them by name to Velocity. Use the property resource.loader and list one or more loader names. You can use anything you want - these names are used to associate configuration properties with a given loader. resource.loader = file

    該例子表明我們有了一個叫做"file"的資源加載器了,接下來的事情就是為該加載器配置重要的屬性,其中最重要的就是申明該加載器的類型:That entry declares that we will have a resource loader known as 'file'. The next thing to do is to set the important properties. The most critical is to declare the class to use as the loader : file.resource.loader.class =
    org.apache.velocity.runtime.resource.loader.FileResourceLoader

    在這個例子中,我們?yōu)閒ile加載器指定了類型------org.apache.velocity.runtime.resource.loader.FileResourceLoader 。下面繼續(xù)配置其他的屬性。In this case, we are telling velocity that we are setting up a resource loadercalled 'file', and are using the class org.apache.velocity.runtime.resource.loader.FileResourceLoaderto be the class to use. The next thing we do is set the properties important to this loader. file.resource.loader.path = /opt/templates
    file.resource.loader.cache = true
    file.resource.loader.modificationCheckInterval = 2

    在這里,我們設(shè)置了一些值。首先,我們把模版加載的路徑設(shè)為/opt/templates;接著,把緩存打開;最后,把模版變化檢查間隔設(shè)置為2秒,讓Velocity檢查時候有新的模版。Here, we set a few things. First, we set the path to find the templates to be /opt/templates. Second, we turned caching on, so that after a template or static file is read in, it is cached in memory. And finally, we set the modification check interval to 2 seconds, allowing Velocity to check for new templates.

    上面這些都是最基礎(chǔ)的配置,下面會是一些特殊的配置了:Those are the basics. What follows are a few examples of different configuraitons.

    默認的配置Do-nothing Default Configuration : 同名字一樣,該配置除了加載默認的配置以外不做任何改變。該配置適用FileResourceLoader,將當(dāng)前路徑作為默認的資源路徑,并關(guān)閉緩存。As the name says, there is nothing you have to do or configure to get the default configuration. This configuration uses the FileResourceLoader with the current directory as the default resource path, and caching is off. As a properties set, this is expressed as : resource.loader = file

    file.resource.loader.description = Velocity File Resource Loader
    file.resource.loader.class =
    org.apache.velocity.runtime.resource.loader.FileResourceLoader
    file.resource.loader.path = .
    file.resource.loader.cache = false
    file.resource.loader.modificationCheckInterval = 0

    多模版路徑配置Multiple Template Path Configuration : 該配置適用了FileResourceLoader,并設(shè)置了多個資源加載路徑,同樣,開啟了緩存,并將檢查時間設(shè)置為10秒:This configuration uses the FileResourceLoader with several directories as 'nodes' on the template search path. We also want to use caching, and have the templates checked for changes in 10 second intervals. As a properties set, this is expressed as : resource.loader = file

    file.resource.loader.description = Velocity File Resource Loader
    file.resource.loader.class =
    org.apache.velocity.runtime.resource.loader.FileResourceLoader
    file.resource.loader.path = /opt/directory1, /opt/directory2
    file.resource.loader.cache = true
    file.resource.loader.modificationCheckInterval = 10

    多加載器配置Multiple Loader Configuration : 該配置同時設(shè)置了3個資源加載器------FileResourceLoader;ClasspathResourceLoader, and the和JarResourceLoader。在該配置中,FileResourceLoader會被首先使用,然后是ClasspathResourceLoader最后是JarResourceLoader。這允許你快速的把一個模版放入模版路徑中,而不需要放入類路徑中,也不需要重新打包為jar文件。This configuration sets up three loaders at the same time, the FileResourceLoader, the ClasspathResourceLoader, and the JarResourceLoader. The loaders are set-up such that the FileResourceLoader is consulted first, then the ClasspathResourceLoader, and finally the JarResourceLoader. This would allow you to qickly drop a template into the file template area to replace on of the templates found in the classpath (usually via a jar) without having to rebuild the jar. #

    1. specify three resource loaders to use
      #
      resource.loader = file, class, jar

    #

    1. for the loader we call 'file', set the FileResourceLoader as the
    2. class to use, turn off caching, and use 3 directories for templates
      #
      file.resource.loader.description = Velocity File Resource Loader
      file.resource.loader.class =org.apache.velocity.runtime.resource.loader.FileResourceLoader
      file.resource.loader.path = templatedirectory1, anotherdirectory, foo/bar
      file.resource.loader.cache = false
      file.resource.loader.modificationCheckInterval = 0

    #

    1. for the loader we call 'class', use the ClasspathResourceLoader
      #
      class.resource.loader.description = Velocity Classpath Resource Loader
      class.resource.loader.class =org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader

    #

    1. and finally, for the loader we call 'jar', use the JarResourceLoader
    2. and specify two jars to load from
      #
      jar.resource.loader.description = Velocity Jar Resource Loader
      jar.resource.loader.class =org.apache.velocity.runtime.resource.loader.JarResourceLoader
      jar.resource.loader.path =jar:file:/myjarplace/myjar.jar, jar:file:/myjarplace/myjar2.jar

    注意,"file,class,jar"這三個名字僅僅是為了方便,你可以取任何你想要的名字------他們只是把一組屬性連接起來的名字。不過,我們也建議你使用能直接表示資源加載器類型的名字。Node that the three names 'file', 'class', and 'jar' are merely for your convenience and sanity. They can be anything you want - they are just used to associate a set of properties together. However, it is recommended that you use names that give some hint of the function.

    最后注意,即便這三種加載器的配置都很簡單,但是,ClasspathResourceLoader應(yīng)該是最常用的。Note that while all three require very little configuration information for proper operation, the ClasspathResourceLoader is the simplest. 可插拔的資源管理器和資源緩存Pluggable Resource Manager and Resource Cache資源管理系統(tǒng)中,資源管理器應(yīng)該是最重要的了。負責(zé)響應(yīng)應(yīng)用對模版的請求,用合適的資源加載器加載,并選擇是否緩存被解析了的模版。資源緩存是資源管理器用來緩存模版并快速重用的機構(gòu)。默認版本的這兩個設(shè)施能滿足絕大多數(shù)應(yīng)用的需求了,更高級的用戶現(xiàn)在也能使用自定義的資源管理器和資源緩存了。The Resource Manager is the main part of the resource (template and static content) management system, and is responsible for taking application requests for templates, finding them in the available resource loaders, and then optionally caching the parsed template. The Resource Cache is the mechanism that the Resource Manager uses to cache templates for quick reuse. While the default versions of these two facilities are suitable for most applications, for advanced users it now is possible to replace the default resource manager and resource cache with custom implementations.

    要實現(xiàn)資源管理器需要實現(xiàn)org.apache.velocity.runtime.resource.ResourceManager 接口。要闡述如何實現(xiàn)一個資源管理器已經(jīng)超出了本指南的范圍了,建議要實現(xiàn)自己的資源管理器的開發(fā)者看看默認的資源管理器的實現(xiàn)。要讓Velocity加載你自己的管理器,需要配置下面的屬性:A resource manager implementation must implement the org.apache.velocity.runtime.resource.ResourceManager interface. A description of the requirements of a resource manager is out of scope for this document. Implementors are encouraged to review the default implementation. To configure Velocity to load the replacement implementation, use the configuration key : resource.manager.class

    該關(guān)鍵字被定義為RuntimeConstants.RESOURCE_MANAGER_CLASS 。This key is also defined as a contstant RuntimeConstants.RESOURCE_MANAGER_CLASS

    要實現(xiàn)資源緩存器需要實現(xiàn)org.apache.velocity.runtime.resource.ResourceCache接口。要闡述如何實現(xiàn)一個資源緩存器已經(jīng)超出了本指南的范圍了,建議要實現(xiàn)自己的資源緩存器的開發(fā)者看看默認的資源緩存器的實現(xiàn)。要讓Velocity加載你自己的緩存器,需要配置下面的屬性:A resource cache implementation must implement the org.apache.velocity.runtime.resource.ResourceCache interface As with the resource manager, a description of the requirements of a resource manager is out of scope for this document. Implementors are encouraged to review the default implementation. To configure Velocity to load the replacement implementation, use the configuration key : resource.manager.cache.class

    該關(guān)鍵字被定義為:RuntimeConstants.RESOURCE_MANAGER_CACHE_CLASS 。This key is also defined as a contstant RuntimeConstants.RESOURCE_MANAGER_CACHE_CLASS

    Template Encoding for Internationalization

    在Velocity1.1種,允許你設(shè)置模版資源的編碼格式了。設(shè)置編碼格式的API如下:As of version 1.1, Velocity allows you to specify the character encoding of your template resources on a template by template basis. The normal resource API's have been extended to take the encoding as an argument :

    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 )

    作為參數(shù)傳入的編碼格式必須是你JVM支持的正規(guī)的編碼。比如UTF-8或者ISO-8859-1。在here察看官方的字符集名稱。The value for the encoding argument is the conventional encoding specification supported by your JVM, for example "UTF-8" or "ISO-8859-1". For the official names for character sets, see here.

    注意,這里設(shè)置的只是模版本身的編碼格式,輸出的編碼格式是應(yīng)用的一個單獨的設(shè)置。Note that this applies only to the encoding of the template itself - the output encoding is an application specific issue.
    Velocity and XML Velocity靈活和簡單的模版語言使他成為一個理想的和XML數(shù)據(jù)一起工作的環(huán)境。Anakia 是一個使用Velocity來代替XSL來為XML合成輸出的例子。Velociyt官方網(wǎng)站和所有的文檔,都是使用Anakia來從XML資源中合成的。Jakarta網(wǎng)站也是如此。Velocity's flexibility and simple template language makes it an ideal environment for working with XML data. Anakia is an example of how Velocity is used to replace XSL for rendering output from XML. The Velocity site, including this documentation, is generated from XML source using Anakia. The Jakarta site is also rendered using Anakia.

    簡單來說,Velocity處理XML的模式和使用JDOM處理XML到一個數(shù)據(jù)結(jié)構(gòu)的模式比較相像。然后,你在XML文件之外定義你的模版來連接從XML中解析的數(shù)據(jù)。比如,下面是一個XML文檔:Generally, the pattern for dealing with XML in Velocity is to use something like JDOM to process your XML into a data structure with convenient Java access. Then, you produce templates that access data directly out of the XML document - directly though the JDOM tree. For example, start with an XML document such as : <?xml version="1.0"?>

    <document>
    <properties>
    <title>Developer's Guide</title>
    <author email="geirm@apache.org">Velocity Documentation Team</author>
    </properties>
    </document>

    然后創(chuàng)建一個Java程序:Now make a little Java program that includes code similar to: ...

    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 );...

    (請參見Anakia的代碼來了解更多細節(jié),或者察看Anakia的例子See the Anakia source for details on how to do this, or the Anakia example in the examples directory in the distribution.) 現(xiàn)在,編寫一個簡單的Velocity模版:Now, make a regular Velocity template : <html>
    <body>
    The document title is
    $root.getChild("document").getChild("properties").getChild("title").getText()
    </body>
    </html>

    然后使用上下文對象中的JDOM樹合成模版。當(dāng)然,這不是最完美的例子,但是他也展示了一些基礎(chǔ)的東西------你能在Velocity模版中很容易的得到XML的數(shù)據(jù)。and render that template as you normally would, using the Context containing the JDOM tree. Of course, this isn't the prettiest of examples, but it shows the basics - that you can easily access XML data directly from a Velocity template.

    一個真正的把XML數(shù)據(jù)納入Velocity的優(yōu)勢在于,你同時也能訪問應(yīng)用提供的對象。你不僅僅限制于XML中的數(shù)據(jù),你能向輸出中添加任何你需要的東西,或者提供一些幫助處理XML數(shù)據(jù)的工具。Bob McWhirter的 Werken Xpath工具就是這樣一個很有用的工具------一個該工具在Anakia中的使用的例子可以在org.apache.velocity.anakia.XPathTool中找到。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.

    Velocity和XML

    一起使用會出現(xiàn)一個問題,就是怎樣處理XML標(biāo)簽。一個技巧是使用Velocity宏來把一個XML標(biāo)簽放入輸出流中。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

      1. and use it as

    #set( $sometext = " < " )
    <text>#xenc($sometext)</text>

    其中的escapeEntities()方法為你完成去除工作。另一種方法是創(chuàng)建一個編碼工具,并使用上下文作為構(gòu)造方法的參數(shù)或者實現(xiàn)一個方法。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)
    {
    Object obj = context.get(key)
    return (obj != null) ? Escape.getText( obj.toString() ) : "";
    }

    把該對象作為"xenc"并放入上下文中。然后象下面這樣使用:Put it into the context as "xenc". Then you can use it as : <text>$xenc.sometext</text>

    這使用了Velocity的自省的優(yōu)勢---他會嘗試調(diào)用上下文中的$xenc對象的get("sometext")方法-----然后xenc對象會從上下文中得到值,并編碼,返回。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.

    此外,當(dāng)Velocity使自定義上下文對象的使用變得很簡單,你完全可以實現(xiàn)自己的總是能編碼的上下文。小心,不能直接調(diào)用方法來合成輸出,因為在這里面可能會有對象或者需要編碼的String。將他們使用#set放入上下文中,并象這樣使用: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() )
    <text>$sometext</text>

    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

    posted on 2007-04-05 23:48 朱巖 閱讀(6246) 評論(1)  編輯  收藏 所屬分類: Velocity文章

    評論

    # re: Velocity開發(fā)者指南 2014-09-15 22:13 zuidaima

    velocity demo教程源代碼下載地址:http://zuidaima.com/share/kvelocity-p1-s1.htm  回復(fù)  更多評論   


    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 久久亚洲AV无码精品色午夜麻| 中文字幕在线观看亚洲视频| 久久久免费的精品| 亚洲第一街区偷拍街拍| 亚洲人成网站影音先锋播放| 免费人成年激情视频在线观看| 免费女人高潮流视频在线观看| 色吊丝性永久免费看码| 亚洲精品无码久久| 亚洲欧美国产日韩av野草社区| 亚洲视频国产视频| 亚洲av日韩av高潮潮喷无码| 国产gv天堂亚洲国产gv刚刚碰| 免费人成网站7777视频| 日本特黄特色aa大片免费| 国产网站在线免费观看| 国产一级淫片免费播放| 国产三级免费电影| 在线A亚洲老鸭窝天堂| 好看的电影网站亚洲一区| 亚洲日本va在线视频观看| 亚洲成av人影院| 亚洲精品无码久久毛片波多野吉衣 | 免费无码AV一区二区| 特级毛片全部免费播放| aa毛片免费全部播放完整| 91在线免费视频| 免费在线观看的网站| 国产成人涩涩涩视频在线观看免费| 亚洲成av人片不卡无码久久| 亚洲中文字幕伊人久久无码| 亚洲av日韩综合一区在线观看| 亚洲综合久久一本伊伊区| 日韩一级片免费观看| 永久在线免费观看| 亚洲综合av永久无码精品一区二区| 337p日本欧洲亚洲大胆色噜噜 | 少妇人妻偷人精品免费视频| 成全影视免费观看大全二| 久久亚洲国产精品123区| 久久夜色精品国产噜噜亚洲a|