1Velocity用户指南什么是Velocity?Velocity是基于Java的模板引擎。它允许Web页面开发者引用Java代码中定义的方法。Web设计者可以和Java程序开发者并行开发遵循MVC模式的Web站点。这意味着,Web设计者可以将精力放在好的Web站点设计上,而Java程序开发者可以将精力放在编写代码上。Velocity将Java代码从Web页面中分离,使Web站点更具长期可维护性,并提供了一种替代JSP或PHP的方案。VTL(VelocityTemplateLanguage)介绍VTL提供一种简单、容易和干静的方法将动态内容合并到Web页面。VTL使用引用(references)将动态内容插入到Web页面中。变量是一种引用,可以指向Java代码中的定义内容,或者由Web页面中的VTL语句来获得值。下面是一个可以插入到HTML文档的VTL语句的例子:#set($a=Velocity)VTL语句以#开头,并包含指令(set)。变量以$开头,用引号引起。引号可以是单引号,也可以是双引号。前者引用具体的String值;后者可以包含Velocity引用,例如”hello,$name”,$name会用其当前的值替换。上面的例子是将值Velocity赋值给变量a。当变量被赋值后,就可以在HTML文档的任何地方引用,下面是HelloVelocityWorld!的例子:htmlbody#set($foo=Velocity)Hello$fooWorld!/bodyhtml注释VTL支持单行注释(以##开始)和多行注释(包括在#*和*#之间),下面是一个例子:Thistextisvisible.##Thistextisnotvisible.Thistextisvisible.Thistextisvisible.#*Thistext,aspartofamulti-linecomment,isnotvisible.Thistextisnotvisible;itisalsopartofthe2multi-linecomment.Thistextstillnotvisible.*#Thistextisoutsidethecomment,soitisvisible.##Thistextisnotvisible.引用VTL有3种类型的引用:变量、属性和方法。作为一个设计者,必须和Java工程师在VTL引用的名称(标识符)上一致,以便在模板中使用它们。引用是作为String对象处理的。(1)变量变量的格式:$VTL标识符VTL标识符以字母开始,由字母、数字、横划线(-)或下划线(_)组成。变量或者从模板中的set指令获得值(如前面的例子),或者Java代码(同名变量)中获得值。Velocity只处理已定义的变量引用,对于没有定义的变量引用,Velocity原样返回。例如下面的例子:#set($foo=gibbous)$moon=$foo输出结果是:$moon=gibbous(2)属性属性的格式:$VTL标识符.VTL标识符下面是属性引用的例子:$customer.Address$purchase.Total拿第一例子来说,有两种意思:返回Hashtable对象customer中键值为Address的值$customer.getAddress()方法引用的缩写(JavaBean属性的getter方法)至于是哪种情况,Velocity会做决定,返回合适的值。(3)方法方法的格式:$VTL标识符(参数列表)下面是方法引用的例子:$customer.getAddress()$purchase.getTotal()$page.setTitle(MyHomePage)$person.setAttributes([Strange,Weird,Excited])3前面两个例子可以缩写成属性引用(如属性引用的例子)。属性引用和方法引用的主要区别是方法引用可以指定参数列表。(4)正式引用符号:{}正式引用符号在使用变量引用含糊的地方进行区分。看下面的例子:#set($vice=klepto)Jackisa$vicemaniac.输出结果是:Jackisa$vicemaniac.($vicemaniac没有定义,原样输出)#set($vice=klepto)Jackisa${vice}maniac.输出结果是:Jackisakleptomaniac.(使用正式引用符号将$vice和其它文本区分开)(5)Quit引用符号:!看下面的例子:inputtype=textname=emailvalue=$email/初始时,$email没有值,所以文本框中会显示值$email,而更希望是空白。下面是使用Quit引用符号的例子:inputtype=textname=emailvalue=$!email/当$email没有值时,Velocity会用空串替代$email。(6)特殊字符转义对于$、#等特殊字符要正常显示,可以使用\进行转义,\\转义为\。下面是一个例子:#set($email=foo)$email\$email\\$email\\\$email输出结果是:foo$email\foo\$email指令(Directives)引用允许模板设计者为Web站点生成动态内容,而指令使巧妙处理Java代码的脚本元素容易使用。4(1)#set格式:#set(LHS=RHS)LHS可以是变量引用或属性引用RHS可以是引用、字符串、数字、ArrayList或Map下面的例子展示了上面的每种RHS类型:#set($monkey=$bill)##variablereference#set($monkey.Friend=monica)##stringliteral#set($monkey.Blame=$whitehouse.Leak)##propertyreference#set($monkey.Plan=$spindoctor.weave($web))##methodreference#set($monkey.Number=123)##numberliteral#set($monkey.Say=[Not,$my,fault])##ArrayList#set($monkey.Map={banana:good,roastbeef:bad})##Map对于ArrayList和Map,可以使用对应的Java方法访问其中的元素值:$monkey.Say.get(0)$monkey.Map.get(bannana)$monkey.Map.banana##sameasaboveRHS可以是简单的算术表达式#set($value=$foo+1)##Addition#set($value=$bar-1)##Subtraction#set($value=$foo*$bar)##Multiplication#set($value=$foo/$bar)##Division#set($value=$foo%$bar)##Remainder算术表达式只支持整型。/的结果为整数;如果非整型数值,返回null如果RHS的结果为null,是不会赋值给LHS的看下面的例子:#set($criteria=[name,address])#foreach($criterionin$criteria)#set($result=$query.criteria($criterion))#if($result)Querywassuccessful#end5#end上面使用$result检查是否执行成功是有问题的。如果第一次执行成功,$result不为null,则后面的执行不管是否成功,检查条件总是成立。改进的方法是在每次执行前初始化为false:#set($criteria=[name,address])#foreach($criterionin$criteria)#set($result=false)#set($result=$query.criteria($criterion))#if($result)Querywassuccessful#end#endString文字可以使用双引号或单引号括起。两者的主要区别是双引号中的引用会替换成相应的值,而单引号中的引用原样输出#set($directoryRoot=)#set($templateName=index.vm)#set($template=$directoryRoot/$templateName)$template输出结果是:如果使用单引号:#set($template='$directoryRoot/$templateName’)输出结果是:$directoryRoot/$templateName使用双引号可以实现字符串的串联,如下面的例子:#set($size=Big)#set($name=Ben)#set($clock=${size}Tall$name)Theclockis$clock.(2)#if/#elseif/#else#if指令在条件成立时,显示#if和#end之间的内容,否则显示#else和#end之间的内容。下面是一个例子:#if($foo)strongVelocity!/strong6#end条件成立有两种情况:如果$foo是boolean,则$foo要为true;否则,$foo不为null#if指令中可以使用的关系和逻辑符号包括:、=、==、=、&&(and)、||(or)、!(not)(3)循环:foreach下面是一个例子:ul#foreach($productin$allProducts)li$product/li#end/ul$allProducts的内容可以是Vector、Hashtable或ArrayList,每次取出一个值赋值给$product;返回的值是一个Java对象,可以用来引用具体的方法。下面的例子假设$allProducts是Hashtable对象:ul#foreach($keyin$allProducts.keySet())liKey:$key-Value:$allProducts.get($key)/li#end/ulVelocity提供了访问循环计数变量的简单方法:table#foreach($customerin$customerList)trtd$velocityCount/tdtd$customer.Name/td/tr#end/table$velocityCount是Velocity表示循环计数的内部变量,缺省开始值为1。该设置在velocity.properties文件中定义:#Defaultnameoftheloopcounter#variablereference.7directive.foreach.counter.name=velocityCount#Defaultstartingvalueoftheloop#countervariablereference.directive.foreach.counter.initial.value=1可以在#foreach指令中使用范围操作符[n..m],其中n和m必须是整型:Firstexample:#foreach($fooin[1..5])$foo#endSecondexample:#foreach($barin[2..-2])$bar#endThirdexample:#set($arr=[0..1])#foreach($iin$arr)$i#end输出结果是:Firstexample:12345Secondexample:210-1-2Thirdexample:01(4)#include#include指令导入本地文件到#include指令定义的地方。导入的文件内容不会被模板引擎解析。出于