Velocity官方指南-使用Velocity

移动开发
如果你使用的是VelocityViewServlet或者其他的web框架,你不会直接调用到Velocity。但是,如果在非web的应用中或者自己编写的web框架时,你将会像上面说的基本流程一样直接调用到Velocity 引擎。另外一个需要记住的重点是,必须在使用Velocity合并模版之前,初始化Velocity引擎。

[[143748]]

如果你使用的是VelocityViewServlet或者其他的web框架,你不会直接调用到Velocity。但是,如果在非web的应用中或者自己编写的web框架时,你将会像上面说的基本流程一样直接调用到Velocity 引擎。另外一个需要记住的重点是,必须在使用Velocity合并模版之前,初始化Velocity引擎。

Velocity辅助类

Velocity中包含一个叫做Velocity( org.apache.velocity.app.Velocity )的应用工具类。这个类的主要是提供一些初始化Velocity时必须的方法,以及简化Velocity使用的一些常规方法。这个在工程的javadoc中有描述,可通过阅读javadoc来获取更详细的说明。本篇文档只是教程;所以,如果需要了解完整的API信息,javadoc是你***的选择。

Velocity运行时引擎是为在同一个jvm中的其他使用者提供资源获取,日志记录等其他服务的单个实例。因此,运行时引擎只会初始化一次。你可以尝试初始化多次,但是只有***次是有效的,后面的初始化操作都会被忽略。Velocity工具类提供了五个用来配置运行时引擎的方法。

这五个配置方法如下:

  • setProperty( String key, Object o )
    设置属性键key对应属性值为o。值通常为字符串,在特殊情况下也可以是逗号分隔的一串值(如”foo,bar,woogie”),当然也可以其他值。
  • Object getProperty( String key )
    获取属性键key对应的值。需要注意的是返回值的类型,不仅仅只是字符串类型
  • init()
    使用jar包中的默认properties文件中配置的属性初始化运行时引擎
  • init(Properties p)
    使用类型为java.util.Properties参数出入的属性来初始化运行时引擎
  • init( String filename )
    使用文件名为filename的properties文件中的属性值初始化运行时引擎

需要注意的是,在上面的这五个方法中,默认的properties是基础的配置,额外的properties是用来替换默认配置中对应的属性。没有被替换的默认属性还将继续发挥作用。这有利于你只需替换你感兴趣的,而不需要整个都替换掉。

另外需要注意的是,init() 方法可以在应用中被调用多次,这并不会带来其他影响。但是只有在***调用时的引擎配置才会生效,后面调用的init()使用的配置都会被忽略。

最常见的初始化Velocity的方式,通常如下:
1 按照org/apache/velocity/runtime/defaults/velocity.properties 文件中的格式配置你需要替换的属性,放在文件中或者放到java.util.Properties中,然后调用init(filename) 或者 init(Properties)
2 通过setProperty() 方法设置单个的配置项,然后调用initial()。 这种方法通常在拥有自己的配置管理系统的高层应用中。例如,允许应用基于运行时产生的值来配置Velocity

一旦运行时引擎初始化完成,你就可以进行任何你想做的了。当然,主要还是围绕着渲染模板输出内容到输出流中,Velocity辅助类中的一些方法可以帮你轻松搞定,下面是这些方法以及他们做的事情的简要描述:

  • evaluate( Context context, Writer out, String logTag, String instring )
  • evaluate( Context context, Writer writer, String logTag, InputStream instream )这些方法使用传入的contexxt对象渲染一个输入,输出到Writer中;输入的内容可以是一个字符串或者一个InputStram。这个方法经常用在替换字符串中的标记、渲染模板内容保存在数据库中或其他的非文具的存储中,或者动态生成内容时。
  • invokeVelocimacro( String vmName, String namespace, String params[], Context context, Writer writer )
    通过这个方法可以直接调用到Velocity宏,也可以通过上面的evalutae()方法调用。你只需要给你的vm模板取一个名字,创建一个提供给vm使用的数组,一个包含数据的context,以及用于输出内容的Writer。需要注意的是这里说的提供给vm使用的数组中的元素只能是context中有的key,而不是其他用作参数传入vm的字符串。这点在后面的版本有可能修改。
  • mergeTemplate( String templateName, Context context, Writer writer )通过这个方法可以非常方便的调用到Velocity提供的模板出来和渲染的功能。这个方法会读取和渲染模板。文件加载器会根据你设置的properties的设置来加载模板内容,所以可以Velocity提供的文件处理的优势以及预解析模板缓存的优势。
  • boolean templateExists( String name )判断当前配置的资源加载起能否都让渠道名为name的模板文件。

通过上面的文档,我们已经清楚了这些基础的辅助方法,现在就可以地编写使用Velocity的java程序了:

  1. import java.io.StringWriter; 
  2. import org.apache.velocity.app.Velocity; 
  3. import org.apache.velocity.VelocityContext; 
  4.   
  5. public class Example2 
  6.     public static void main( String args[] ) 
  7.     { 
  8.         /* 首先,初始化运行时引擎,使用默认的配置 */ 
  9.   
  10.         Velocity.init(); 
  11.   
  12.         /* 创建Context对象,然后把数据放进去 */ 
  13.   
  14.         VelocityContext context = new VelocityContext(); 
  15.   
  16.         context.put("name""Velocity"); 
  17.         context.put("project""Jakarta"); 
  18.   
  19.         /* 渲染模板 */ 
  20.   
  21.         StringWriter w = new StringWriter(); 
  22.  
  23.         Velocity.mergeTemplate("testtemplate.vm", context, w ); 
  24.         System.out.println(" template : " + w ); 
  25.   
  26.         /* 渲染字符串 */ 
  27.   
  28.         String s = "We are using $project $name to render this."
  29.         w = new StringWriter(); 
  30.         Velocity.evaluate( context, w, "mystring", s ); 
  31.         System.out.println(" string : " + w ); 
  32.     } 

在运行程序之前,我们需要把模板文件testtemplate.vm放到与程序相同的目录下(因为我们使用默认配置,默认配置中指定的模板加载路径就是程序的当前目录)。运行上面代码后,将会输出:

template : Hi! This Velocity from the Jakarta project.
string : We are using Jakarta Velocity to render this.

模板文件testtemplate.vm文件的内容是:

Hi! This $name from the $project project.

好了,上面就是我们使用Velocity渲染模板需要做的事情了。在代码中没有必要既调用mergeTemplate()又调用evaluate(),这里只是为了演示才同时使用了。你一般只需要使用其中一个方法就够了。但是到底调用一个还是两个,需要根据你程序的具体要求确定。

这里看起来与文章最开始描述的 基本流程 有一些差别,但实际是他们是相同的。首先,你还是需要先创建一个context,放进你需要的数据。上面描述的例子中不同的是使用了mergeTemplate()方法,mergeTemplate()方法调用了底层的Runtime类中的方法加载了模板,然后合并内容。在上面的第二个例子中,通过字符串动态创建模板,这个操作就类同于基本模式中的选择模板的操作;后面的merge()方法就调用了底层的方法来合并模板内容。

所以上面的例子跟文章开始描述的 基本流程 是一样,只不过这里的一些工具方法做了那些重复的苦力活;同时也演示了除了从模板文件中获取模板内容外,你也可以动态的创建模板内容。

异常

Velocity在解析和合并模板的过程中可能会抛出异常。这些异常都继承RuntimeException,所以没有显式捕获的必要,每一种异常都包含了特定的属性以提供给***的调用者来获知异常的具体信息。这些异常类都放在了org.apache.velocity.exception包下,有如下几种:

1. ResourceNotFoundException
当资源管理系统找不到请求的相应资源时抛出。
2. ParseErrorException
在解析Velocity模板语法是出现错误时抛出
3.TemplateInitException
在模板解析的***个阶段抛出,提示Velocity宏或者指令初始化时出现的错误
4.MethodInvocationException
在渲染模板时调用Context中某个对象的方法是出现错误时抛出。该异常包装了调用对象的方法抛出的异常并传递给应用,让你能够在运行时处理这些对象中的问题。

在每次抛出上面的这些异常时都会记入到运行日志中。可通过阅读javadoc api 文档了解更多详细信息。

其他细节

虽然上面的代码中使用的是默认属性,但是设置自定义的属性也是非常简单的。你需要做的就是创建一个properties文件,在文件中添加你需要自定义的属性,然后传递文件的路径给Velocity工具类中的init(String)方法;或者创建一个java.util.Poperties 对象,往这个对象中自定义的属性,然后传递给Velocity工具类的init(Properties)方法。后一种方式显得灵活些,因为你可以通Properties的load()方法加载一个properties文件,更好的是你应用或框架中动态传入运行时设置的属性。你可以方便的将应用用到的所有属性组合放到一个properties文件中。

如果你想从其他目录而非当前目录中加载模板文件,我们可以通过下面这种方式来完成

  1. ... 
  2.  
  3. import java.util.Properties; 
  4.  ... 
  5.  
  6. public static void main( String args[] ) 
  7.     /* 首先,我们还是初始化运行时引擎  */ 
  8.   
  9.     Properties p = new Properties(); 
  10.     p.setProperty("file.resource.loader.path", "/opt/templates"); 
  11.     Velocity.init( p ); 
  12.   
  13.  ... 

为了能顺利运行上面的代码,你需要有一个 /opt/templates 目录,并且把文件testtemplate.vm放到该目录下。如果你按照上面的做了,还是出现问题,可以查看velocity.log文件确定具体原因,毕竟阅读错误日志是你定位问题的不二选择。

  1. ... 
  2.   
  3.    VelocityEngine velocityEngine = new VelocityEngine(); 
  4.    ExtendedProperties eprops = null
  5.    if (props==null) { 
  6.       eprops = new ExtendedProperties(); 
  7.    } else { 
  8.       eprops = ExtendedProperties.convertProperties(props); 
  9.    } 
  10.   
  11.    // 现在,我们用一个对象实例来设置属性 
  12.    eprops.setProperty("name", object); 
  13.   
  14.    ... 
  15.    velocityEngine.setExtendedProperties(eprops); 
  16.    velocityEngine.init(); 
  17.    ... 

你可以考虑尝试使用下面章节描述的[应用属性]特性。

责任编辑:倪明 来源: 并发编程网
相关推荐

2012-11-20 11:26:19

Velocity Ch

2011-11-30 10:28:43

Velocity Ch

2011-12-09 14:43:55

O'Reilly VeCompuwaredynaTrace

2014-04-30 12:04:43

Velocity.js模板引擎

2015-08-12 19:31:46

性能魔方

2012-12-13 14:39:13

Velocity

2016-12-07 10:41:03

2011-10-26 10:43:19

Sencha Touc

2012-01-10 13:21:33

Sencha Touc使用data包

2011-10-26 10:21:40

Sencha Touc组件

2015-09-18 14:07:34

O'Reilly Me

2012-12-24 10:42:05

IT技术周刊

2011-10-26 10:32:05

Sencha Touc数据视图

2014-08-17 14:36:22

基调网络mAPM

2011-06-17 16:23:49

Cocoa苹果

2017-01-09 09:51:08

微信小程序

2011-06-17 15:57:46

CocoaXcode苹果

2017-06-30 09:36:10

Android OAPI兼容

2011-06-15 17:02:02

CocoaiOS

2023-09-01 15:20:12

点赞
收藏

51CTO技术栈公众号