您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 销售管理 > 使用Velocity 实现客户端和服务器端模板
使用Velocity实现客户端和服务器端模板灵活的模板引擎为JSP技术提供一种没有遗产负担的选择级别:初级SingLi(westmakaha@yahoo.com),作家,WroxPress2004年3月13日Velocity是一种通用的、开放源代码的模板解决方案,可以在报告生成/数据转换应用程序中独立使用,也可以在MVC模型框架中作为视图组件。本文中,SingLi介绍了Velocity,并说明如何将其模板处理功能集成到客户端独立应用程序、服务器端Web应用程序或者Web服务中。在HTML或者XML这样的标准表示或交换格式中,文本性数据的操作和转换是一种频繁而且通常非常单调的活动,每个开发人员都会遇到。模板引擎可以改善这个过程,它在模板中保留输出中的静态部分,而动态生成和安排变化的部分。Velocity是一种高度实用的、开放源代码的模板引擎,可以方便地集成到其他客户端或服务器端应用程序中。对于服务器端应用程序,如果与兼容Servlet2.3+的Web层容器集成,Velocity为JSP技术提供了一种可行的替代方案,可以强制实施表示逻辑与应用程序业务逻辑的清晰划分。事实上,Velocity支持的模板语言非常简单,形成的模板也十分清晰,Web站点设计人员和样式开发人员可以学习和维护这些模板。本文中将考察Velocity的简单模板语言、创建一些模板并将其用于独立的客户应用程序。然后我们将把这个模板引擎集成到StrutsMVC框架中作为视图组件。基本模板引擎操作基本模板引擎操作非常简单。首先看一看清单1中的模板:清单1.基本的Velocity模板htmlheadtitleATemplateBasedPage/title/headbodypThisisapagegeneratedby$generatedBy./ppThecustomer'snameis$customerName./p/body/html这个模板是一个完整的HTML文件。您可以使用文本编辑器或者喜欢的图形化可视网页编辑器创建该文件。创建的简易性是基于模板的系统的主要好处和要求。当模板引擎运行时,清单1中彩色显示的部分将被实际的数据替换。获取数据并与模板结合的过程称为合并。看一看清单2中的脚本所表示的数据:清单2.为模板合并设置数据值#set($generatedBy=Velocity)#set($customerName=JohnDoe)文档选项将此页作为电子邮件发送未显示需要JavaScript的文档选项现在,如果清单1中的模板与清单2中的数据合并,将得到清单3所示的结果:清单3.合并到模板中的数据htmlheadtitleATemplateBasedPage/title/headbodypThisisapagegeneratedbyVelocity./ppThecustomer'snameisJohnDoe./p/body/html您可能发现,这种特性和字处理程序中的邮件合并功能类似。在字处理程序中,信函结构与来自邮件列表的名称和地址合并。和邮件合并一样,这种应用程序最适用于要合并的数据源非常大而且有变化的情况。从这个单纯的意义上讲,Velocity是一个模板引擎。Velocity的输出格式仅受文本模板中所能放置的内容的限制。包括现在最流行的格式(HTML、XML、SQL,等等)。使用Velocity模板语言创建模板Velocity模板是文本文件(HTML、XML等等),其中包括:照原样合并的静态部分将被要合并的数据替代的占位符脚本语言中的指示符和指令Velocity模板使用的脚本语言称为Velocity模板语言(VTL)。和其他脚本语言相比,VTL语法相对而言不是很丰富。任何具有编程背景的人都可以非常快地学会VTL。占位符与引用VTL中的引用是一个命名元素,如$customerName。引用可以在Velocity模板中作为占位符。在模板合并过程中,这些占位符将被替换成相应的文本值,从而形成最终的输出。比如,在清单1中,我们可以看到使用了两个VTL引用($generatedBy和$customerName)已生成最终输出结果。变量在VTL中是一种引用类型。您可以使用#set()指示符为变量赋值。清单4给出了一些例子:清单4.变量类型的VTL引用#set($this=Velocity)#set($numericBase=999)#set($booleanCondition=true)Thispageisgeneratedusing$this.Thereare($numericBase+1)pagesintotal.变量名必须从一个字母开始,因此Velocity很容易把变量名与模板中的货币符号分开(比如,$100不可能是一个变量名)。合并操作中所有的变量都被转化成字符串,可能造成一些有趣的现象。看一看清单4中用红色显示的文本。合并后的输出如清单5所示:清单5.合并后的模板中带有数字值的变量ThispageisgeneratedusingVelocity.Thereare(999+1)pagesintotal.因为$numericBase在合并操作中被转化成了字符串,因此不会执行算术操作。因为VTL专门用于模板操作而非通用的计算语言,所以只需要支持整数算术运算(尽管可以使用插件工具进行扩展)。下面的脚本说明了如何利用这种数学运算能力:#set($newSum=$numericBase+1)Thereare$newSumpagesintotal.该模板合并后相应的输出为:Thereare1000pagesintotal.到目前我们处理的还只有标量。要创建包含多个元素的ArrayList变量,可以使用如下的语法:#set($treeList=[pine,oak,maple,redwood])您可以使用$treeList.get(1)列表中的第二个元素。赋值以后,$treeList就是一个基于ArrayList的变量(就像是标准JDK集合类中那样)。您可以直接使用符号$treeList.get(n)访问它的每个元素,其中的n是以0为基的ArrayList索引。比如,像清单6种红色显示的一行所表明的那样,$treeList.get(1)用于选择ArrayList中第二项,即oak。这种调用ArrayList类方法的语法也可用于调用其他变量对象的方法(更多信息请参阅侧栏中的属性和方法参考)。关于占位符替换的一点说明:Velocity把任何不能识别的引用作为普通文本打印,如清单6中下面突出显示的两行(蓝色和红色)所示:清单6.占位符置换Theseconditeminthelistis$treeList.get(1).$notDeclaredisanundeclaredvariable.But$!notDeclaredisinvisiblewhennotdeclared.属性和方法参考除了在模板中设置变量之外,VTL引用也可以是对象属性或方法。这些对象是模板可以使用的Java类(一般通过上下文,参阅Velocity上下文)。对象属性通过和Javabean类似的符号访问。比如,可以通过VTL引用$customer.LastName访问$customer对象的LastName属性。在幕后,Velocity使用对象的访问器方法获得属性值(即调用对象的getLastName()方法)。您可以用和属性访问类似的符号调用对象的方法,可以带参数列表也可以不带。比如,可以通过VTL引用$customer.getPhone(mobile),调用$customer对象的getPhone()方法获得移动电话号码。VTL支持一种静态引用符号,以避免呈现不存在的或者空的引用。如果使用安静引用符号,比如$!notDeclared,那么Velocity将什么也不输出,而不是输出完整的引用名。注意变量名前面的“!”表示这是静态引用符号。当合并清单6中的模板时,两个引用都没有分配任何值,但是蓝色显示的引用将原样显示,而绿色的一个则看不到:Theseconditeminthelistisoak.$notDeclaredisanundeclaredvariable.Butisinvisiblewhennotdeclared.选择性呈现和循环可以使用指示符#if...#then...#else....有条件地呈现模板中特定的部分。清单7给出了一个例子:清单7.使用#if、#then和#else有选择地呈现#if$customer.GoldMemberThankyouMr.$customer.LastName,forflyingwithus.Yourloyalpatronageisgreatlyappreciated.Thisflightearnsyouanadditional5000miles.#elseThankyouforflyingwithus.Pleaseconsiderjoiningourfrequentflyerprogram.#endif在清单7的模板中,使用$customer对象的boolean属性GoldMember确定在最终输出中出现哪些信息。对于金牌顾客,最终输出中将呈现蓝色显示的消息;对于其他顾客,则在最终输出中呈现绿色显示的消息。模板中经常要使用循环格式化表格或者列表形式的信息。显示的数据通常保存在一个ArrayList引用中。在Velocity中唯一用于处理重复循环的指示符是#foreach指示符。清单8中的模板通过$treeListArrayList变量演示了#foreach指示符的用法。当然,也可以使用任何其他可用的集合类型的对象引用,或者返回一个集合的对象属性/方法引用。清单8.使用#foreach循环tabletrtdTreeName/td/tr#foreach$namein$treeListtrtd$nameisabigtree!/td/tr#end/table$treeList中包含树名的列表,清单8中的模板合并后的输出如清单9所示:清单9.#foreach循环中合并后的输出tabletrtdTreeName/td/trtrtdpineisabigtree!/td/trtrtdoakisabigtree!/td/trtrtdmapleisabigtree!/td/trtrtdredwoodisabigtree!/td/tr/table如果从HTML浏览器中查看,清单9当然就是一个包含树名的表。注意在#foreach循环体内有一个内置的计数器,可以在#foreach指示符循环体内通过$velocityCounter引用访问它。默认情况下,这个计数器从1开始,每执行一次循环递增一次。Velocity中的宏Velocity的一个主要特性是能够很容易地定义宏,称为Velocimacros。宏使您能够很容易地封装和重用模板脚本。默认情况下,宏保存在VM_global_library.vm文件中。比如,考虑清单10中名为#showTree()的Velocimacro:清单10.定义Velocimacro#macro(showTree)#if($treeList)#foreach($ein$treeList)$e#end#end#end您可以调用#showTree()Velocimacro并使用它打印$treeListArrayList――如果这个列表已经定义的话。调用的语法很简单,即#showTree()。参数化宏也是可能的。比如,我们可以修改#showTree()宏使其用于任何列表,如清单11所示:清单11.带参数的Velocimacro#macro(showList$val)#if($val)#foreach($ein$val)$e#end#end#en
本文标题:使用Velocity 实现客户端和服务器端模板
链接地址:https://www.777doc.com/doc-1584887 .html