当前位置: 首页 > 科技观察

Velocity官方指南-使用Velocity

时间:2023-03-12 16:30:08 科技观察

如果你使用的是VelocityViewServlet或其他web框架,你不会直接调用Velocity。但是,如果你是在一个非web应用或者自己写的web框架中,你会像上面说的基本流程一样直接调用Velocity引擎。另一件需要记住的重要事情是,在使用Velocity合并模板之前必须初始化Velocity引擎。Velocity辅助类Velocity包含一个名为Velocity(org.apache.velocity.app.Velocity)的应用工具类。该类的主要目的是提供一些初始化Velocity所必需的方法,以及一些常用的方法来简化Velocity的使用。这个在项目的javadoc中有描述,你可以通过阅读javadoc得到更详细的说明。本文档只是一个教程;因此,如果您需要完整的API信息,javadoc是您的最佳选择。Velocity运行时引擎是一个单一的实例,它为同一个jvm中的其他用户提供资源获取、日志记录和其他服务。因此,运行时引擎只会被初始化一次。可以尝试多次初始化,但只有第一次有效,后续的初始化操作将被忽略。VelocityUtilities类提供了五种配置运行时引擎的方法。五种配置方法如下:setProperty(Stringkey,Objecto)将属性键key对应的属性值设置为o。值通常是一个字符串,特殊情况下也可以是逗号分隔的一串值(比如“foo,bar,woogie”),当然其他值也是可以的。ObjectgetProperty(Stringkey)获取属性键key对应的值。需要注意的是返回值的类型不只是字符串类型init()使用jar包中默认属性文件配置的属性来初始化运行引擎init(Propertiesp)使用java.util的类型.Properties参数进入和退出属性初始化运行时引擎init(Stringfilename)使用名为filename的属性文件中的属性值初始化运行时引擎。需要注意的是,在以上五种方法中,默认的属性是基础配置,附加的属性用于替换默认配置中的相应属性。未被覆盖的默认属性将继续起作用。这对您只替换您感兴趣的而不是替换整个东西很有好处。另一件需要注意的事情是,init()方法可以在应用程序中多次调用而不会产生任何其他影响。但是只有***调用时的引擎配置才会生效,后面调用的init()使用的配置会被忽略。初始化Velocity最常见的方式通常如下:1在org/apache/velocity/runtime/defaults/velocity.properties文件中按照格式配置你需要替换的属性,放到文件中或者java中.util.Properties,然后调用init(filename)或init(Properties)2通过setProperty()方法设置单个配置项,然后调用initial()。这种方法通常用于具有自己的配置管理系统的更高级别的应用程序。例如,允许应用程序根据运行时生成的值来配置Velocity一旦运行时引擎被初始化,你就可以为所欲为。当然,主要是围绕着将模板输出内容渲染到输出流。Velocity辅助类中的一些方法可以轻松帮助你。以下是这些方法及其作用的简要说明:evaluate(Contextcontext,Writerout,StringlogTag,Stringinstring)evaluate(Contextcontext,Writerwriter,StringlogTag,InputStreaminstream)这些方法使用传入的contextxt对象来渲染输入并将其输出到Writer;输入内容可以是字符串或InputStram。当替换字符串中的标记、呈现存储在数据库或其他非固定存储中的模板内容或动态生成内容时,通常会使用此方法。invokeVelocimacro(StringvmName,Stringnamespace,Stringparams[],Contextcontext,Writerwriter)通过这个方法可以直接调用Velocity宏,也可以通过上面的evalutae()方法调用。你只需要给你的虚拟机模板一个名字,创建一个数组供虚拟机使用,一个包含数据的上下文,以及一个用于输出内容的Writer。需要注意的是,这里所说的提供给vm的数组中的元素只能是context中的key,不能是其他作为参数传递给vm的字符串。这可能会在以后的版本中进行修改。mergeTemplate(StringtemplateName,Contextcontext,Writerwriter)通过这个方法可以很方便的调用Velocity提供的模板输出和渲染功能。此方法将读取并呈现模板。文件加载器会根据你设置的属性设置加载模板内容,这样你就可以利用Velocity提供的文件处理和预解析模板缓存的优势。booleantemplateExists(Stringname)判断当前配置的资源是否可以加载频道名称的模板文件。通过上面的文档,我们明确了这些基本的辅助方法,现在我们就可以编写使用Velocity的Java程序了:{publicstaticvoidmain(Stringargs[]){/*首先,初始化运行时引擎,使用默认配置*/Velocity.init();/*创建一个Context对象,并将数据放入其中*/VelocityContextcontext=newVelocityContext();context.put("name","Velocity");context.put("project","Jakarta");/*渲染模板*/StringWriterw=newStringWriter();Velocity.mergeTemplate("testtemplate.vm",context,w);System.out.println("template:"+w);/*渲染字符串*/Strings="Weareusing$project$nametorenderthis.";w=newStringWriter();Velocity.evaluate(context,w,"mystring",s);System.out.println("string:"+w);}}在运行程序之前,我们需要将模板文件testtemplate.vm放到与程序同目录下(因为我们使用的是默认配置,模板加载路径默认配置中指定的是程序的当前目录)。运行上面的代码后,会输出:template:Hi!ThisVelocityfromtheJakartaproject.string:我们正在使用JakartaVelocity来渲染它。模板文件testtemplate.vm文件内容为:Hi!这个$name来自$project项目。好了,以上就是我们使用Velocity渲染模板需要做的事情。代码中不需要调用mergeTemplate()和evaluate(),同时使用只是为了演示。您通常只需要使用其中一种方法。但是调用一个还是两个取决于你程序的具体要求。看起来和文章开头描述的基本流程有些区别,其实是一样的。首先,您仍然需要创建一个上下文并放入您需要的数据。上述示例的不同之处在于使用了mergeTemplate()方法。mergeTemplate()方法调用底层Runtime类中的方法加载模板,然后合并内容。在上面的第二个例子中,模板是通过字符串动态创建的。该操作类似于基本模式下选择模板的操作;merge()方法稍后调用底层方法来合并模板内容。所以上面的例子和文章开头描述的基本过程是一样的,只是这里的一些工具和方法做了那些重复性的辛苦工作;它还演示了除了从模板文件中获取模板内容之外,您还可以动态创建模板内容。异常Velocity在解析和合并模板时可能会抛出异常。这些异常都继承了RuntimeException,所以不需要显式捕获。每个异常都包含特定属性以向最新异常的调用者提供特定信息。这些异常类都放在org.apache.velocity.exception包下,具体如下:1.ResourceNotFoundException当资源管理系统找不到请求的对应资源时抛出。2.解析Velocity模板语法错误时抛出ParseErrorException3.模板解析第一阶段抛出TemplateInitException,表示Velocity宏或指令初始化时发生错误4.渲染模板时调用MethodInvocationException对象的方法是抛出错误。异常将调用对象的方法抛出的异常包装起来传递给应用程序,让你在运行时处理这些对象中的问题。每次抛出上述异常,都会记录在运行日志中。可以通过阅读javadocapi文档找到更多详细信息。其他细节虽然上面的代码使用了默认属性,但是设置自定义属性也非常简单。你需要做的就是创建一个properties文件,在文件中添加你需要自定义的属性,然后将文件的路径传递给Velocity工具类中的init(String)方法;或者创建一个java.util.Poperties对象,将这个对象中的自定义属性传递给Velocity工具类的init(Properties)方法。后一种方法更灵活,因为你可以通过Properties的load()方法加载一个属性文件,最好在你的应用程序或框架中动态传入运行时设置的属性。您可以轻松地将应用程序使用的所有属性组合到一个属性文件中。如果你想从其他目录而不是当前目录加载模板文件,我们可以通过以下方式实现...importjava.util.Properties;...publicstaticvoidmain(Stringargs[]){/*首先,我们还是initializeRuntimeengine*/Propertiesp=newProperties();p.setProperty("file.resource.loader.path","/opt/templates");Velocity.init(p);...为了运行上面的代码顺利地,你需要有一个/opt/templates目录,并将文件testtemplate.vm放在该目录中。如果按照以上步骤还是有问题,可以查看velocity.log文件来确定具体原因。毕竟阅读错误日志是你定位问题的最佳选择。...VelocityEnginevelocityEngine=newVelocityEngine();ExtendedPropertiesprops=null;if(props==null){eprops=newExtendedProperties();}else{eprops=ExtendedProperties.convertProperties(props);}//现在,我们使用对象实例设置属性eprops.setProperty("name",object);...velocityEngine.setExtendedProperties(eprops);velocityEngine.init();...您可以考虑尝试使用以下部分中描述的[ApplicationProperties]功能.