??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲国产综合精品一区在线播放,亚洲午夜AV无码专区在线播放,亚洲国产成人无码AV在线http://m.tkk7.com/jackybu/category/2394.html<a ><b><font color=red>共有<script src=http://fastonlineusers.com/online.php?d=jackybu.blogjava.net></script>人在同时阅读此Blog</font></b></a>zh-cnTue, 27 Feb 2007 20:39:37 GMTTue, 27 Feb 2007 20:39:37 GMT60Velocity用户手册---中文?/title><link>http://m.tkk7.com/jackybu/articles/8805.html</link><dc:creator>?/dc:creator><author>?/author><pubDate>Sat, 30 Jul 2005 14:32:00 GMT</pubDate><guid>http://m.tkk7.com/jackybu/articles/8805.html</guid><wfw:comment>http://m.tkk7.com/jackybu/comments/8805.html</wfw:comment><comments>http://m.tkk7.com/jackybu/articles/8805.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/jackybu/comments/commentRss/8805.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/jackybu/services/trackbacks/8805.html</trackback:ping><description><![CDATA[<div id="akimu8m" class=forumcontent>创徏人:王艺<BR>?:javamail@263.net<BR>QQP179985017<BR><BR><B>Velocity是什么?</B><BR>Velocity是一个基于java的模板引擎(template engineQ。它允许MZ仅简单的使用模板语言Qtemplate languageQ来引用由java代码定义的对象?BR>当Velocity应用于web开发时Q界面设计h员可以和javaE序开发h员同步开发一个遵循MVC架构的web站点Q也是_面设计人员可以只关注页面的昄效果Q而由javaE序开发h员关注业务逻辑~码。Velocityjava代码从web面中分d来,q样为web站点的长期维护提供了便利Q同时也为我们在JSP和PHP之外又提供了一U可选的Ҏ?BR>Velocity的能力远不止web站点开发这个领域,例如Q它可以从模板(templateQ生SQL和PostScript、XMLQ它也可以被当作一个独立工h产生源代码和报告Q或者作为其他系l的集成lg使用。Velocity也可以ؓTurbine web开发架构提供模板服务(template serviceQ。Velocity+Turbine提供一个模板服务的方式允许一个web应用以一个真正的MVC模型q行开发?BR><BR><B>Velocity能ؓ我们作什么?</B><BR>The Mud Store Example <BR>假设你是一家专门出售Mud的在U商店的面设计人员Q让我们暂且U它为“在UMUD商店”。你们的业务很旺Q客户下了各U类型和数量的mud订单。他们都是通过输入用户名和密码后才登陆C的网站,登陆后就允许他们查看订单q购买更多的mud。现在,一U非常流行的mud正在打折销售。另外有一些客戯律性的购买另外一U也在打折但是不是很行的Bright Red MudQ由于购买的人ƈ不多所以它被安|在面的边~。所有用L信息都是被跟tƈ存放于数据库中的Q所以某天有一个问题可能会冒出来:Z么不使用velocity来用户更好的浏览他们感兴趣的商品呢Q?BR>Velocity使得web面的客户化工作非常Ҏ。作Z个web site的设计h员,你希望每个用L陆时都拥有自q面?BR>你会见了一些公司内的Y件工E师Q你发现他们每个人都同意客户应该拥有h个性化的信息。那让我们把软g工程师应该作的事情发在一边,看一看你应该作些什么吧?BR>你可能在面内嵌套如下的VTL声明Q?BR><PRE class=overflow title="pre code"><html><BR><body><BR>Hello $customer.Name!<BR><table><BR>#foreach( $mud in $nudsOnSpecial ) <BR>#if ( $customer.hasPurchased( $mud ) ) <BR><tr><td>$flogger.getPromo( $mud )</td></tr><BR>#end<BR>#end<BR></table></PRE><BR><BR>Velocity Template Language(VTL):AN introduction<BR>VTL意味着提供最单、最Ҏq且最整洁的方式合q面动态内宏V?BR>VTL使用references来在web site内嵌套动态内容,一个变量就是一U类型的reference。变量是某种cd的refreenceQ它可以指向java代码中的定义Q或者从当前面内定义的VTL statement得到倹{下面是一个VTL statement的例子,它可以被嵌套到HTML代码中:<BR>#set ( $a = “Velocity?)<BR>和所有的VTL statement一Pq个statement以#字符开始ƈ且包含一个directiveQset。当一个在U用戯求你的页面时QVelocity Templating Engine查询整个页面以便发现所有#字符Q然后确定哪些是VTL statementQ哪些不需要VTL作Q何事情?BR>Q字W后紧跟一个directiveQsetӞq个set directive使用一个表辑ּQ用括号封闭)――一个方E式分配一个值给变量。变量被列在左边Q而它的D列在双Q最后他们之间用=号分剌Ӏ?BR>在上面的例子中,变量?aQ而它的值是Velocity。和其他的references一样以$字符开始,而值L以双引号闭。Velocity中仅有String可以被赋值给变量?BR>C以下的规则:<BR>使用$字符开始的references用于得到什么;使用#字符开始的directives用于作些什么?BR>Hello Velocity World!<BR>一旦某个变量被分配了一个|那么你就可以在HTML文g的Q何地方引用它。在下面的例子中Q一个D分配l?foo变量Qƈ在其后被引用?BR><PRE class=overflow title="pre code"><html><BR><body><BR>#set ( $foo = “Velocity?)<BR>Hello $foo World!<BR></body><BR></html></PRE><BR>上面的实现结果是在页面上打印“Hello Velocity WorldQ?BR>Z使包含VTL directives的statement更具有可L,我们鼓励你在新行开始每个VTL statementQ尽你不是必须q么作。Set directive在后面详细描述?BR>注释<BR>单行注释Q?BR>## This is a single line comment.<BR>多行注释Q?BR>#*<BR>Thus begins a multi-line comment. Online visitors won’t<BR>see this text because the Velocity Templating Engine will<BR>ignore it.<BR>*#<BR>文档格式Q?BR>#**<BR>This is a VTL comment block and<BR>may be used to store such information<BR>as the document author and versioning<BR>information:<BR>@version 5<BR>@author<BR>*#<BR><BR>References<BR>在VTL中有三种cd的referencesQ变?variables)、属?properties)、方?methods)。作Z个用VTL的页面设计者,你和你的工程师必dreferences的名U达成共识,以便你可以在你的template中用它们?BR>Everything coming to and from a reference被作Z个String对象处理。如果有一个对?foo是一个Integer对象Q那么Velocity调用它的toString()Ҏ这个对象{型ؓStringcd?BR>变量 <BR>格式要求同java?BR>属?<BR>例子Q?BR>$customer.Address<BR>$purchase.Total<BR>$customer.Address有两U含义。它可以表示Q查找hashtable对象customer中以Address为关键字的|也可以表C用customer对象的getAddress()Ҏ。当你的面被请求时QVelocity确定以上两U方式选用那种Q然后返回适当的倹{?BR>Ҏ <BR>一个方法就是被定义在java中的一D代码,q且它有完成某些有用工作的能力,例如一个执行计和判断条g是否成立、满等。方法是一个由$开始ƈ跟随VTL标识W组成的ReferencesQ一般还包括一个VTLҎ体。例如:<BR>$customer.getAddress()<BR>$purchase.getTotal()<BR>$page.setTitle( “My Home Page?)<BR>$person.setAttributes( [“Strange? “Weird? “Excited”] )<BR>前两个例?customer.getAddress()?purchase.getTotal()看v来挺想上面的属?customer.Address ?$purchase.Total。如果你觉得他们之间有某U联pȝ话,那你是正的?BR>VTL属性可以作为VTLҎ的羃写?customer.Address属性和使用$customer.getAddress()Ҏh相同的效果。如果可能的话用属性的方式是比较合理的。属性和Ҏ的不同点在于你能够给一个方法指定一个参数列表?BR>正式reference标记<BR>reference的正是格式如下:<BR>${mudSlinger} 变量<BR>${customer.Address} 属?BR>${purchase.getTotal()} Ҏ<BR>非正是格式更见常用,但是有时q是使用正是格式比较适合。例如:你希望通过一个变?vice来动态的l织一个字W串?BR>Jack is a $vicemaniac.<BR>本来变量?vice现在却变成了$vicemaniacQ这样Veloctiy׃知道您到底要什么了。所以,应该使用正是格式书写<BR>Jack is a ${vice}maniac<BR>现在Velocity知道变量?vice而不?vicemaniac?BR>Quiet reference notation<BR>例如Q?BR><input type=”text?name=”email?value=?email?/><BR>当页面的form被初始加载时Q变?emailq没有|q时你肯定是希望它能够显CZ个blank text来代替输出?email”这L字段。那么用quiet reference notation比较合适?BR><input type=”text?name=”email?value=?!email?><BR>q样文本框的初始值就不会是email而是Ig?BR>正式和quiet格式的reference notation也可一同用,像下面这P<BR><input type=”text?name=”email?value=?!{email}?><BR>Getting literal <BR>Velocity使用Ҏ字符$?来帮助它工作Q所以如果要在template里用这些特D字W要格外心。本节将讨论$字符?BR>货币字符 <BR>在VTL中?2.5q样的货币标识是没有问题得的QVTL不会它错认为是一个referenceQ因为VTL中的referenceL以一个大写或者小写的字母开始?BR>Escaping valid VTL reference <BR>VTL中用“\”作为逃逸符?BR>例如Q?BR><PRE class=overflow title="pre code">  #set( $email = “foo?)<BR>  $email<BR>  \$email<BR>  \\$email<BR>  \\\$email</PRE><BR><BR>render为:<BR><PRE class=overflow title="pre code">  foo<BR>  $email<BR>  \foo<BR>  \\$email</PRE><BR>如果email变量没有被定义则<BR><PRE class=overflow title="pre code">  $email<BR>  \$email<BR>  \\$email<BR>  \\\$email</PRE><BR>被render为:<BR><PRE class=overflow title="pre code">  $email<BR>  \$email<BR>  \\$email<BR>  \\\$email</PRE><BR>注意QVTL中未被定义的变量被认ؓ是一个字W串Q所以以下例子:<BR><PRE class=overflow title="pre code">  #set( $foo = “gibbous?)<BR>  $moon = $foo</PRE><BR>的输出结果是Q?BR><PRE class=overflow title="pre code">$moon = gibbous<BR>Case substitution</PRE><BR>现在你已l对reference比较熟悉了,你可以将他们高效的应用于你的template了。Velocity利用了很多java规范以方便了设计人员的用。例如:<BR><PRE class=overflow title="pre code">  $foo<BR>  $foo.getBar()<BR>  ## is the same as<BR>  $foo.Bar<BR><BR>  $data.getUser(“jon?<BR>  ## is the same as<BR>  $data.User(“jon?<BR><BR>  $data.getRequest().getServerName()<BR>  # is the same as<BR>  $data.Request.ServerName<BR>  ## is the same as<BR>  ${data.Request.ServerName}</PRE>但是Q注意VTL中不会将reference解释为对象的实例变量。例如:$foo.Name被解释为Foo对象的getNameQ)ҎQ而不是Foo对象的Name实例变量?BR>Directives<BR>Reference允许设计者用动态的内容Q而directive使得你可以应用java代码来控制你的显C逻辑Q从而达C所期望的显C效果?BR>#set <BR>#set directive被用于设|一个reference的倹{例如:<BR>#set ( $primate = “monkey?)<BR>#set ( $customer.Behavior = $primate )<BR>赋值左侧的QLHSQ必L一个变量或者属性reference。右侧(RHSQ可以是以下cd中一U:<BR><PRE class=overflow title="pre code">l  变量reference<BR>l  String literal<BR>l  属性reference<BR>l  Ҏreference<BR>l  number literal<BR>l  ArrayList</PRE>下面是应用各U类型的RHS的例子:<BR><PRE class=overflow title="pre code">  Qset ( $monkey = $bill ) ##变量reference<BR>  Qset ( $monkey.Friend = “monica?) ##String literal<BR>  Qset ( $monkey.Blame = $whitehouse.Leak )##属性reference<BR>  Qset ( $monkey.Plan = $spindoctor.weave($web) )##Ҏreference<BR>  Qset ( $monkey.Number = 123 )##Number literal<BR>  Qset ( $monkey.Say = [“Not? $my, “fault”] )##ArrayList</PRE>注意Q最后一个例子的取值方法ؓQ?monkey.Say.get(0)<BR>RHS也可以是一个简单的术表达式:<BR><PRE class=overflow title="pre code">  #set ( $value = $foo + 1 )<BR>  #set ( $value = $bar -1 )<BR>#set ( $value = $foo * $bar )<BR>#set ( $value = $foo / $bar )</PRE><BR>如果你的RHS是一个nullQVTL的处理将比较ҎQ它指向一个已l存在的referenceQ这对初学者来讲可能是比较费解的。例如:<BR><PRE class=overflow title="pre code">#set ( $resut = $query.criteria(“name? )<BR>  The result of the first query is $result<BR><BR>  #set ( $resut = $query.criteria(“address? )<BR>  The result of the second query is $result</PRE><BR>如果$query.criteria(“name?q回一个“bill”,?query.criteria(“address?q回的是nullQ则昄的结果如下:<BR>The result of the first query is bill<BR>The result of the first query is bill<BR>看看下面的例子:<BR><PRE class=overflow title="pre code">#set( $criteria = ["name", "address"] )<BR>#foreach( $criterion in $criteria )<BR>#set( $result = $query.criteria($criterion) )<BR>  #if( $result )<BR>  Query was successful<BR>     #end<BR>#end</PRE><BR>在上面的例子中,E序不能智能的Ҏ$result的值决定查询是否成功。在$result?set后(added to the contextQ,它不能被讄回nullQremoved from the contextQ。打印的l果显CZơ查询结果都成功了,但是实际上有一个查询是p|的?BR>Z解决以上问题我们可以通过预先定义的方式:<BR>#set( $criteria = [“name? “address”] )<BR>#foreach( $criterion in $criteria )<BR>#set( $result = false )<BR>#set( $result = $query.criteria( $criterion ) )<BR>#if( $result )<BR>Query was successful<BR>#end<BR>#end<BR>String Literals <BR>当你使用#set directiveQString literal闭在一对双引号内?BR>#set ( $directoryRoot = “www?)<BR>#set ( $templateName = “index.vm?)<BR>#set ( $template = ?directoryRoot/$tempateName?)<BR>$template<BR>上面q段代码的输出结果ؓQwww/index.vm<BR>但是Q当string literal被封装在单引号内Ӟ它将不被解析Q?BR>#set ( $foo = “bar?)<BR>$foo<BR>#set ( $blargh = ?foo?)<BR>l果Q?BR>bar<BR>$foo<BR>上面q个Ҏ可以通过修改velocity.properties文g的stringliterals.interpolate = false的值来改变上面的特性是否有效?BR>条g语句<BR>if/elseif/else <BR>当一个web面被生成时使用Velocity?if directriveQ如果条件成立的话可以在面内嵌入文字。例如:<BR>#if ( $foo )<BR><strong>Velocity!</strong><BR>#end<BR>上例中的条g语句在以下两种条g下成立:<BR>l $foo是一个boolean型的变量Q且它的gؓtrue<BR>l $foo变量的g为null<BR>q里需要注意一点:Velocity context仅仅能够包含对象Q所以当我们说“boolean”时实际上代表的时一个Boolean对象。即便某个方法返回的是一个boolean|Velocity也会利用内省机制它转换Z个Boolean的相同倹{?BR>如果条g成立Q那?if?end之间的内容将被显C?BR>#elseif?else元素可以?if一同用。例如:<BR><PRE class=overflow title="pre code">#if( $foo < 10 )<BR>    <strong> Go North </strong><BR>  #elseif( $foo == 10 )<BR>    <strong> Go East </strong><BR>  #elseif( $foo == 6 )<BR>    <strong> Go South </strong><BR>  #else<BR>    <strong> Go West </strong><BR>  #end</PRE><BR>注意q里的Velocity的数字是作ؓInteger来比较的――其他类型的对象得条件ؓfalseQ但是与java不同它用“=Q”来比较两个|而且velocity要求{号两边的值类型相同?BR>关系、逻辑q算W?<BR>Velocity中用等h作符判断两个变量的关pR例如:<BR><PRE class=overflow title="pre code">#set ( $foo = “deoxyribonucleic acid?)<BR>#set ( $bar = “ribonucleic acid?)<BR>#if ( $foo == $foo )<BR>  In this case it’s clear they aren’t equivalent.So?BR>#else<BR>  They are not equivalent and this will be the output.<BR>#end</PRE><BR><BR>Velocity有AND、OR和NOT逻辑q算W。下面是一些例子:<BR>## logical AND<BR>#if( $foo && $bar )<BR><strong> This AND that </strong><BR>#end<BR><BR>## logical OR<BR>#if ( $foo || $bar )<BR><strong>This OR That </strong><BR>#end<BR><BR>##logical NOT<BR>#if ( !$foo )<BR><strong> NOT that </strong><BR>#end<BR>循环 <BR>Foreach循环 <BR>例子Q?BR><ul><BR>#foreach ( $product in $allProducts )<BR><li> $product </li><BR>#end<BR></ul><BR>每次循环$allProducts中的一个值都会赋l?product变量?BR>$allProducts可以是一个Vector、Hashtable或者Array。分配给$product的值是一个java对象Qƈ且可以通过变量被引用。例如:如果$product是一个java的Productc,q且q个产品的名字可以通过调用他的getNameQ)Ҏ得到?BR>现在我们假设$allProducts是一个HashtableQ如果你希望得到它的key应该像下面这P<BR><ul><BR>#foreach ( $key in $allProducts.keySet() )<BR><li>Key: $key -> Value: $allProducts.get($key) </li><BR>#end<BR></ul><BR><BR>Velocityq特别提供了得到循环ơ数的方法,以便你可以像下面q样作:<BR><table><BR>#foreach ( $customer in $customerList )<BR><tr><td>$velocityCount</td><td>$customer.Name</td></tr><BR>#end<BR></table><BR>$velocityCount变量的名字是Velocity默认的名字,你也可以通过修改velocity.properties文g来改变它。默认情况下Q计C?”开始,但是你可以在velocity.properties讄它是从?”还是从?”开始。下面就是文件中的配|:<BR><PRE class=overflow title="pre code"># Default name of loop counter<BR>  # variable reference<BR>  directive.foreach.counter.name = velocityCount<BR><BR>  # Default starting value of the loop<BR>  # counter variable reference<BR>  directive.foreach.counter.initial.value = 1</PRE><BR><BR>include<BR>#include script element允许模板设计者引入本地文件。被引入文g的内容将不会通过模板引擎被render。ؓ了安全的原因Q被引入的本地文件只能在TEMPLATE_ROOT目录下?BR>#inclued ( “one.txt?)<BR>如果您需要引入多个文Ӟ可以用逗号分隔pQ?BR>#include ( “one.gif? “two.txt? “three.htm?)<BR>在括号内可以是文件名Q但是更多的时候是使用变量的:<BR>#inclue ( “greetings.txt? $seasonalstock )<BR><BR>parse<BR>#parse script element允许模板设计者一个包含VTL的本地文件。Velocity解析其中的VTLqrender模板?BR>#parse( “me.vm?)<BR>像#includeQ?parse接受一个变量而不是一个模ѝQ何由#parse指向的模杉K必须包含在TEMPLATE_ROOT目录下。与#include不同的是Q?parse只能指定单个对象?BR>你可以通过修改velocity.properties文g的parse_direcive.maxdepth的值来控制一个template可以包含的最?parse的个数――默认值是10?parse是可以递归调用的,例如Q如果dofoo.vm包含如下行:<BR>Count down.<BR>#set ( $count = 8 )<BR>#parse ( “parsefoo.vm?)<BR>All done with dofoo.vm!<BR>那么在parsefoo.vm模板中,你可以包含如下VTLQ?BR>$count<BR>#set ( $count = $count ?1 )<BR>#if ( $count > 0 )<BR>#parse( “parsefoo.vm?)<BR>#else<BR>All done with parsefoo.vm!<BR>#end<BR>的显C结果ؓQ?BR>Count down.<BR>8<BR>7<BR>6<BR>5<BR>4<BR>3<BR>2<BR>1<BR>0<BR>All done with parsefoo.vm!<BR>All done with dofoo.vm!<BR><BR>Stop<BR>#stop script element允许模板设计者停止执行模板引擎ƈq回。把它应用于debug是很有帮助的?BR>#stop<BR><BR>Velocimacros<BR>#macro script element允许模板设计者定义一D可重用的VTL template。例如:<BR>#macro ( d )<BR><tr><td></td></tr><BR>#end<BR>在上面的例子中Velocimacro被定义ؓdQ然后你可以在MVTL directive中以如下方式调用它:<BR>#d()<BR>当你的template被调用时QVelocity用<tr><td></td></tr>替换?d()?BR>每个Velocimacro可以拥有L数量的参数――甚?个参敎ͼ虽然定义时可以随意设|参数数量,但是调用q个Velocimacro时必L定正的参数。下面是一个拥有两个参数的VelocimacroQ一个参数是color另一个参数是arrayQ?BR>#macro ( tablerows $color $somelist )<BR>#foreach ( $something in $somelist )<BR><tr><td bgcolor=$color>$something</td</tr><BR>#end<BR>#end<BR><BR>调用#tablerows VelocimacroQ?BR>#set ( $greatlakes = [ “Superior? “Michigan? “Huron? “Erie? “Ontario?] )<BR>#set ( $color = “blue?)<BR><table><BR>#tablerows( $color $greatlakes )<BR></table><BR>l过以上的调用将产生如下的显C结果:<BR><table><BR><tr><td bgcolor=?blue?gt; Superior </td></tr><BR><tr><td bgcolor=?blue?gt; Michigan </td></tr><BR><tr><td bgcolor=?blue?gt; Huron </td></tr><BR><tr><td bgcolor=?blue?gt; Erie </td></tr><BR><tr><td bgcolor=?blue?gt; Ontario </td></tr><BR></table><BR>Velocimacros可以在Velocity模板内实现行内定义(inlineQ,也就意味着同一个web site内的其他Velocity模板不可以获得Velocimacros的定义。定义一个可以被所有模板共享的Velocimacro昄是有很多好处的:它减了在一大堆模板中重复定义的数量、节省了工作旉、减了出错的几率、保证了单点修改?BR>上面定义?tablerows( $color $list )Velocimacro被定义在一个Velocimacros模板?在velocity.properties中定?里,所以这个macro可以在Q何规范的模板中被调用。它可以被多ơ应用ƈ且可以应用于不同的目的。例如下面的调用Q?BR>#set ( $parts = [ “volva? “stipe? “annulus? “gills? “pileus?] )<BR>#set ( $cellbgcol = ?CC00FF?)<BR><table><BR>#tablerows( $cellbgcol $parts )<BR></table><BR>上面VTL生如下的输出Q?BR><table><BR><tr><td bgcolor=?CC00FF?gt; volva </td</tr><BR><tr><td bgcolor=?CC00FF?gt; stipe </td</tr><BR><tr><td bgcolor=?CC00FF?gt; annulus </td</tr><BR><tr><td bgcolor=?CC00FF?gt; gills </td</tr><BR><tr><td bgcolor=?CC00FF?gt; pileus </td</tr><BR></table><BR><BR>Velocimacro arguments <BR>Velocimacro可以使用以下M元素作ؓ参数Q?BR>l ReferenceQQ何以$开头的reference<BR>l String literalQ?BR>l Number literalQ?BR>l IntegerRangeQ[1?3]或者[$foo?$bar]<BR>l 对象数组Q[“a?”b?”c”]<BR>l boolean|true、false<BR>当将一个reference作ؓ参数传递给VelocimacroӞh意reference作ؓ参数时是以名字的形式传递的。这意味着参数的值在每次Velocimacro内执行时才会被生。这个特性得你可以一个方法调用作为参C递给VelocimacroQ而每ơVelocimacro执行旉是通过q个Ҏ调用产生不同的值来执行的。例如:<BR>#macro ( callme $a )<BR>$a $a $a<BR>#end<BR>#callme( $foo.bar() )<BR>执行的结果是Qreference $foo的barQ)Ҏ被执行了三次?BR>如果你不需要这LҎ可以通过以下ҎQ?BR>#set ( $myval = $foo.bar() )<BR>#callme ( $myval )<BR><BR>Velocimacro properties <BR>Velocity.properties文g中的某几行能够Velocimacros的实现更加灵zR注意更多的内容可以看Developer Guide?BR>Velocity.properties文g中的velocimacro.libraaryQ一个以逗号分隔的模板库列表。默认情况下Qvelocity查找唯一的一个库QVM_global_library.vm。你可以通过配置q个属性来指定自己的模板库?BR>Velocity.properties文g中的velocimacro.permissions.allow.inline属性:有两个可选的值true或者falseQ通过它可以确定Velocimacros是否可以被定义在regular template内。默认值是ture――允许设计者在他们自己的模板中定义Velocimacros?BR>Velocity.properties文g中的<BR>velocimacro.permissions.allow.inline.replace.global属性有两个可选值true和falseQ这个属性允怋用者确定inline的Velocimacro定义是否可以替代全局Velocimacro定义Q比如在velocimacro.library属性中指定的文件内定义的VelocimacroQ。默认情况下Q此gؓfalse。这样就L本地Velocimacro定义覆盖全局定义?BR>Velocity.properties文g中的<BR>velocimacro.permissions.allow.inline.local.scale属性也是有true和false两个可选|默认是false。它的作用是用于定你inline定义的Velocimacros是否仅仅在被定义的template内可见。换句话_如果q个属性设|ؓtrueQ一个inline定义的Velocimacros只能在定义它的template内用。你可以使用此设|实C个奇妙的VM敲门Qa template can define a private implementation of the second VM that will be called by the first VM when invoked by that template. All other templates are unaffected?BR>Velocity.properties文g中的velocimacro.context.localscope属性有true和false两个可选|默认gؓfalse。当讄为trueӞM在Velocimacro内通过#set()对context的修改被认ؓ是针Ҏvelocimacro的本地设|,而不会永久的影响内容?BR>Velocity.properties文g中的velocimacro.library.autoreload属性控制Velocimacro库的自动加蝲。默认是false。当讄为tureӞ对于一个Velocimacro的调用将自动查原始库是否发生了变化,如果变化重新加载它。这个属性得你可以不用重新启动servlet容器而达到重新加载的效果Q就像你使用regular模板一栗这个属性可以用的前提是resource loader~存是off状态(file.resource.loader.cache = falseQ。注意这个属性实际上是针对开发而非产品的?BR><BR>Velocimacro Trivia <BR>Velocimacro必须被定义在他们被用之前。也是_你的#macro()声明应该出现在用Velocimacros之前?BR>特别要注意的是,如果你试?parse()一个包?macro()的模ѝ因?parse()发生在运行期Q但是解析器在parsetiem军_一个看似VM元素的元素是否是一个VM元素Q这?parse()-ing一lVM声明不按照预期的样子工作。ؓ了得到预期的l果Q只需要你单的使用velocimacro.library使得Velocity在启动时加蝲你的VMs?BR>Escaping VTL directives<BR>VTL directives can be escaped with “\”号Q用方式跟VTL的reference使用逃逸符的格式差不多?BR>## #include( “a.txt?) renders as <ontents of a.txt>(注释?<BR>#include( “a.txt?)<BR><BR>## \#include( “a.txt?) renders as \#include( “a.txt?)<BR>\#include( “a.txt?)<BR><BR>## \\#include ( “a.txt?) renders as \<contents of a.txt><BR>\\#include( “a.txt?)<BR>在对在一个directive内包含多个script元素的VTL directives使用逃逸符时要特别心Q比如在一个if-else-end statement内)。下面是VTL的if-statement的典型应用:<BR>#if ( $jazz )<BR>Vyacheslav Ganelin<BR>#end<BR>如果$jazz是tureQ输出将是:<BR>Vyacheslav Ganelin<BR>如果$jazz是falseQ将没有输出。用逃逸符改变输出。考虑一下下面的情况Q?BR>\#if ( $jazz )<BR>Vyacheslav Ganelin<BR>\#end<BR>现在无论$jazz是trueq是falseQ输出结果都是:<BR>#if ( $jazz )<BR>Vyacheslav Ganelin<BR>#end<BR>事实上,׃你用了逃逸符Q?jazzҎ没有被解析为boolean型倹{在逃逸符前用逃逸符是合法的Q例如:<BR>\\#if ( $jazz )<BR>Vyacheslav Ganelin<BR>\\#end<BR>以上E序的显C结果ؓQ?BR>\ Vyacheslav Ganelin<BR>但是如果$jazz为falseQ那么将没有输出。(书上说会没有输出Q但是我觉得应该q有有“\”字W被输出。)<BR>VTLQFormatting issues<BR>管在此用户手册中VTL通常都开始一个新行,如下所C:<BR>#set ( $imperial = [ “Munetaka? “Koreyasu? “Hisakira? “Morikune?] )<BR>#foreach ( $shogun in $imperial )<BR>$shogun<BR>#end<BR>但是像下面这U写法也是可以的Q?BR>Send me #set($foo = [?10 and?”a cake”])#foreach($a in $foo)$a #end please.<BR>上面的代码可以被改写为:<BR>Send me<BR>#set ( $foo = [?10 and ?”a cake”] )<BR>#foreach ( $a in $foo )<BR>$a<BR>#end<BR>please.<BR>或?BR>Send me<BR>#set($foo = [?10 and ?”a cake”])<BR>#foreach Q?a in $foo Q?a<BR>#end please.<BR>q两U的输出l构一栗?BR>其他Ҏ和杂项<BR>math 在模板中可以使用Velocity内徏的算术函敎ͼ如:加、减、乘、除<BR>#set ( $foo = $bar + 3 )<BR>#set ( $foo = $bar - 4 )<BR>#set ( $foo = $bar * 6 )<BR>#set ( $foo = $bar / 2 )<BR>当执行除法时返回一个Integercd的结果。而余C可以使用%来得刎ͼ<BR>#set ( $foo = $bar % 5 )<BR>在Velocity内用数学计公式时Q只能用像-n,-2,-1,0,1,2,nq样的整敎ͼ而不能用其它类型数据。当一个非整型的对象被使用时它被loggedq且以null作ؓ输出l果?BR>Range Operator<BR>Range operator可以被用于与#set?foreach statement联合使用。对于处理一个整型数l它是很有用的,Range operatorh以下构造Ş式:<BR>[n..m]<BR>m和n都必L整型Q而m是否大于n则无关紧要。例子:<BR>First example:<BR>#foreach ( $foo in [1..5] )<BR>$foo<BR>#end<BR><BR>Second example:<BR>#foreach ( $bar in [2..-2] )<BR>$bar<BR>#end<BR><BR>Third example:<BR>#set ( $arr = [0..1] )<BR>#foreach ( $i in $arr )<BR>$i<BR>#end<BR><BR>Fourth example:<BR>[1..3]<BR>上面四个例子的输出结果ؓQ?BR>First exampleQ?BR>1 2 3 4 5<BR><BR>Second exampleQ?BR>2 1 0 -1 -2<BR><BR>Third exampleQ?BR>0 1<BR><BR>Fourth exampleQ?BR>[1..3]<BR>注意Qrange operator只在#set?foreach中有效?BR>Advanced IssueQEscaping andQ?BR>当一个reference被“!”分隔时Qƈ且在它之前有逃逸符Ӟreference以Ҏ的方式处理。注意这U方式与标准的逃逸方式时不同的。对照如下: <BR>#set ( $foo = “bar?)<BR>Ҏ形式 标准格式<BR>Render?Render?Render?Render?BR>$\!foo $!foo \$foo \$foo<BR>$\!{foo} $!{foo} \$!foo \$!foo<BR>$\\!foo $\!foo \$!{foo} \$!{foo}<BR>$\\\!foo $\\!foo \\$!{foo} \bar<BR>Velocimacro杂记<BR>Can I user a directive or another VM as an argument to a VM? <BR>例如Q?center ( #bold( “hello?) )<BR>不可以。一个directive的参C用另外一个directive是不合法的?BR>但是Q还是有些事情你可以作的。最单的方式是使用双引P<BR>#set ( $stuff = ?bold( ‘hello?)?)<BR>#center ( $stuff ) <BR>上面的格式也可以~写Z行:<BR>#center ( ?bold( ‘hello?) )<BR>h意在下面的例子中参数被evaluated在Velocimacro内部Q而不是在calling level。例子:<BR>#macro ( inner $foo )<BR>inner : $foo<BR>#end<BR><BR>#macro ( outer $foo )<BR>#set ( $bar = “outerlala?)<BR>outer : $foo<BR>#end<BR><BR>#set ( $bar = ‘calltimelala?)<BR>#outer( ?inner($bar)?)<BR>输出l果为:<BR>outer : inner : outerlala<BR>CVeloctiy的特性:参数的传递是By Name的。例如:<BR>#macro ( foo $color )<BR><tr bgcolor = $color ><td>Hi</td></tr><BR><tr bgcolor = $color ><td>There</td></tr><BR>#end<BR><BR>#foo ( $bar.rowColor() )<BR>以上代码导致rowColor()Ҏ两次调用Q而不是一ơ。ؓ了避免这U现象的出现Q我们可以按照下面的方式执行Q?BR>#set ( $color = $bar.rowColor() )<BR>#foo ( $color )<BR>can I register velocimacros via #parse()? <BR>目前QVelocimacros必须在第一ơ被模板调用前被定义。这意味着你的#macro()声明应该出现在用Velocimacros之前?BR>如果你试?parse()一个包?macro() directive的模板,q一Ҏ需要牢记的。因?parse()发生在运行期Q但是解析器在parsetiem军_一个看似VM元素的元素是否是一个VM元素Q这?parse()-ing一lVM声明不按照预期的样子工作。ؓ了得到预期的l果Q只需要你单的使用velocimacro.library使得Velocity在启动时加蝲你的VMs?BR>What is velocimacro autoreloadingQ?<BR>velocimacro.library.autoreload是专门ؓ开发而非产品使用的一个属性。此属性的默认值是false?BR>String concatenation<BR>开发h员最帔R的问题是我如何作字符拼接Q在java中是使用“+”号来完成的?BR>在VTL里要惛_现同L功能你只需要将需要联合的reference攑ֈ一起就行了。例如:<BR><PRE class=overflow title="pre code">#set ( $size = “Big?)<BR>#set ( $name = “Ben?)<BR>The clock is $size$name.</PRE><BR>输出l果是QThe clock is BigBen.。更有趣的情冉|Q?BR><PRE class=overflow title="pre code">#set ( $size = “Big?)<BR>  #set ( $name = “Ben?)<BR>  #set ( $clokc = ?size$name?)<BR>  The clock is $clock.</PRE><BR>上例也会得到同样的结果。最后一个例子,当你希望混合固定字段C的referenceӞ你需要用标准格式:<BR><PRE class=overflow title="pre code">#set ( $size = “Big?)<BR>  #set ( $name = “Ben?)<BR>  #set ( $clock = ?{size}Tall$name?)<BR>  The clock is $clock.</PRE><BR>输出l果是:The clock is BigTallBen.。用这U格式主要是Z使得$size不被解释?sizeTall?/DIV><img src ="http://m.tkk7.com/jackybu/aggbug/8805.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/jackybu/" target="_blank">?/a> 2005-07-30 22:32 <a href="http://m.tkk7.com/jackybu/articles/8805.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Velocity?---- from matrixhttp://m.tkk7.com/jackybu/articles/8804.html?/dc:creator>?/author>Sat, 30 Jul 2005 14:31:00 GMThttp://m.tkk7.com/jackybu/articles/8804.htmlhttp://m.tkk7.com/jackybu/comments/8804.htmlhttp://m.tkk7.com/jackybu/articles/8804.html#Feedback0http://m.tkk7.com/jackybu/comments/commentRss/8804.htmlhttp://m.tkk7.com/jackybu/services/trackbacks/8804.html1.Velocity 的?

Velocity是一个开放源吗的模版引擎Q由apache.org组负责开发,现在最新的版本是Velocity1.3.1Qhttp://jakarta.apache.org/velocity/index.html 可以了解Velocity的最C息?
Velocity允许我们在模版中讑֮变量Q然后在q行Ӟ动态的数据插入到模版中,替换q些变量?
例如Q?
<html> 
<body>HELLO $CUSTOMERNAME</body>
</html>
我们可以在运行时得到客户的名字,然后把它插入到这个模版中替换变量$CUSTOMERNAMEQ整个替换过E是由Velocityq行控制的,而且java的调用代码也非常单,如我们可以在java代码中这栯?
/***********************************************************/ 
//q个文g中设定了Velocity使用的log4j的配|和Velocity的模版文件所在的目录
Velocity.init("D:\\Template\\resource\\jt.properties");
//模版文g名,模版文g所在的路径在上一条语句中已经讄?
Template template = Velocity.getTemplate("hello.vm", "gb2312");
//实例化一个Context
VelocityContext context = new VelocityContext();
//把模版变量的D|到context?
context.put("CUSTOMERNAME", "My First Template Engine ---- Velocity.");
//开始模版的替换
template.merge(context, writer);
//写到文g?
PrintWriter filewriter = new PrintWriter(new FileOutputStream(outpath),true);
filewriter.println(writer.toString());
filewriter.close();
/***********************************************************/


q就是整个java的代码,非常的简单。如果我们有多个模版变量Q我们仅需要把q些模版变量的D|到context中?
下面我们单的分析一下,Velocity引擎d模板文gӞ它直接输出文件中所有的文本Q但?字符开头的除外Q?W号标识着一个模版变量位|,
context.put("CUSTOMERNAME", "My First Template Engine ---- Velocity.");
?Velocity 模板引擎解析q输出模板的l果Ӟ模板中所有出?CUSTOMERNAME的地斚w插入客L名字Q即被加入到VelocityContext的对象的toString()Ҏq回值将替代Velocity变量Q模板中?开头的变量Q?
模板引擎中最强大、用最频繁的功能之一是它通过内徏的映像(ReflectionQ引擎查扑֯象信息的能力。这个映像引擎允许用一U方便的Java?”类似的操作W,提取L加入到VelocityContext的对象的M公用Ҏ的|或对象的L数据成员?
映像引擎q带来了另外一个改q:快速引用JavaBean的属性。用JavaBean属性的时候,我们可以忽略getҎ和括受请看下面这个模板的例子?
<html> 
<body>
Name:$Customer.Name()
Address:$Customer.Address()
Age:$Customer.Age()
</body>
</html>


java的代码:
/***********************************************************/ 
//讄客户信息
Customer mycustomer = new Customer();
mycustomer.setName("Velocity");
mycustomer.setAddress("jakarta.apache.org/velocity/index.html");
mycustomer.setAge(2);
//q个文g中设定了 Velocity 使用?Log4j 的配|和Velocity的模版文件所在的目录Velocity.init("D:\\Template\\resource\\jt.properties");
//模版文g名,模版文g所在的路径在上一条语句中已经讄?
Template template = Velocity.getTemplate("hello.vm", "gb2312");
//实例化一个Context
VelocityContext context = new VelocityContext();
//把模版变量的D|到context?
context.put("Customer", mycustomer);
//开始模版的替换
template.merge(context, writer);
//写到文g?
PrintWriter filewriter = new PrintWriter(new FileOutputStream(outpath),true);
filewriter.println(writer.toString());
filewriter.close();
输出l果Q?
<html> 
<body>
Name:Velocity
Address:jakarta.apache.org/velocity/index.html
Age:2
</body>
</html>

除了替换变量之外Q象Velocity高引擎q能做其他许多事情,它们有用来比较和q代的内建指令,通过q些指o我们可以完成E序语言中的条g判断语句和@环语句等?
例如Q我们想要输出年龄等?的所有客L信息Q我们可以这样定义我们的模版
模版Q?
<html> 
<body>
<table>
<tr>
<td>名称</td>
<td>地址</td>
<td>q龄</td>
</tr>
#foreach ($Customer in $allCustomer)
#if($Customer.Age()=="2")
<tr>
<td>$Customer.Name()</td>
<td>$Customer.Address()</td>
<td>$Customer.Age()</td>
</tr>
#end
#end
</table>
</body>
</html>


java的代码:
/******************************************************/ 
//讄客户信息
ArrayList allMyCustomer = new ArrayList();
//客户1
Customer mycustomer1 = new Customer();
mycustomer1.setName("Velocity");
mycustomer1.setAddress("jakarta.apache.org/velocity/index.html");
mycustomer1.setAge(2);
//客户2
Customer mycustomer2 = new Customer();
mycustomer2.setName("Tomcat");
mycustomer2.setAddress("jakarta.apache.org/tomcat/index.html");
mycustomer2.setAge(3);
//客户3
Customer mycustomer3 = new Customer();
mycustomer3.setName("Log4J");
mycustomer3.setAddress("jakarta.apache.org/log4j/docs/index.html");
mycustomer3.setAge(2);
//d到allMyCustomer(ArrayList)?
allMyCustomer.add(mycustomer1);
allMyCustomer.add(mycustomer2);
allMyCustomer.add(mycustomer3);
//q个文g中设定了Velocity使用的log4j的配|和Velocity的模版文件所在的?
Velocity.init("D:\\Template\\resource\\jt.properties");
//模版文g名,模版文g所在的路径在上一条语句中已经讄?
Template template =Velocity.getTemplate("hello.vm", "gb2312");
//实例化一个Context
VelocityContext context = new VelocityContext();
/** 注意q里我们仅仅需要给一个模版变量负?*/
context.put("allCustomer", allMyCustomer);
//开始模版的替换
template.merge(context, writer);
//写到文g?
PrintWriter filewriter = new PrintWriter(new FileOutputStream(outpath),true);
filewriter.println(writer.toString());
filewriter.close();
/******************************************************/
l果Q?
<html> 
<body>
<table>
<tr>
<td>名称</td>
<td>地址</td>
<td>q龄</td>
</tr>
<tr>
<td>Velocity</td>
<td>jakarta.apache.org/velocity/index.html</td>
<td>2</td>
</tr>
<tr>
<td>Log4J</td>
<td>jakarta.apache.org/log4j/docs/index.html</td>
<td>2</td>
</tr>
</table>
</body>
</html>


#if 语句完成逻辑判断Q这个我想不用多说了?
allCustomer对象包含零个或者多个Customer对象。由于ArrayList (List, HashMap, HashTable, Iterator, Vector{?属于Java Collections Framework的一部分Q我们可以用#foreach指oq代其内宏V我们不用担心如何定型对象的cd——映像引擎会为我们完成这个Q务?foreach指o的一般格式是?foreach in ”?foreach指oq代listQ把list中的每个元素攑օitem参数Q然后解?foreach块内的内宏V对于list内的每个元素Q?foreach块的内容都会重复解析一ơ。从效果上看Q它相当于告诉模板引擎说Q“把list中的每一个元素依ơ放入item变量Q每ơ放入一个元素,输出一?foreach块的内容”?

2.MVC设计模型

使用模板引擎最大的好处在于Q它分离了代码(或程序逻辑Q和表现Q输出)。由于这U分,你可以修改程序逻辑而不必担心邮件消息本w;cM圎ͼ你(或公关部门的职员Q可以在不重新编译程序的情况下,重新~写客户列表。实际上Q我们分Mpȝ的数据模式(Data ModelQ即提供数据的类Q、控制器QControllerQ即客户列表E序Q以及视图(ViewQ即模板Q。这U三层体pȝ为Model-View-Controller模型QMVCQ?
如果遵从MVC模型Q代码分成三个截然不同的层,化了软g开发过E中所有相关h员的工作?
l合模板引擎使用的数据模式可以是MJava对象Q最好是使用Java Collection Framework的对象。控制器只要了解模板的环境(如VelocityContextQ,一般这U环境都很容易用?
一些关pL据库的“对?关系”映工兯够和模板引擎很好地协同,化JDBC操作Q对于EJBQ情形也cM?模板引擎与MVC中视图这一部分的关pL为密切。模板语a的功能很丰富、强大,以处理所有必需的视囑֊能,同时它往往很简单,不熟悉编E的Z可以使用它。模板语a不仅使得设计者从q于复杂的编E环境中解脱出来Q而且它保护了pȝQ避免了有意或无意带来危险的代码。例如,模板的编写者不可能~写出导致无限@环的代码Q或侵占大量内存的代码。不要轻估这些安全机制的价|大多数模板编写者不懂得~程Q从长远来看Q避免他们接触复杂的~程环境相当于节省了你自q旉?许多模板引擎的用L信,在采用模板引擎的Ҏ中,控制器部分和视图部分的明分,再加上模板引擎固有的安全机制Q得模板引擎以成为其他内容发布系l(比如JSPQ的替代Ҏ。因此,Java模板引擎最常见的用途是替代JSP也就不为奇了?

3.HTML处理

׃ZL看重模板引擎用来替换JSP的作用,有时他们会忘记模板还有更q泛的用途。到目前为止Q模板引擎最常见的用途是处理HTML Web内容。但我还用模板引擎生成过SQL、email、XML甚至Java源代码?/DIV>

]]>
Velocity 的工作原?--from matrixhttp://m.tkk7.com/jackybu/articles/8803.html?/dc:creator>?/author>Sat, 30 Jul 2005 14:28:00 GMThttp://m.tkk7.com/jackybu/articles/8803.htmlhttp://m.tkk7.com/jackybu/comments/8803.htmlhttp://m.tkk7.com/jackybu/articles/8803.html#Feedback0http://m.tkk7.com/jackybu/comments/commentRss/8803.htmlhttp://m.tkk7.com/jackybu/services/trackbacks/8803.htmlq个E序很简单,但是它能让你清楚的了?Velocity 的基本工作原理。程序中其他部分基本上很固定Q最主要的部分在以下代码

  q里 Velocity 获取模板文gQ得到模板引?BR>
/* next, get the Template */
Template t = ve.getTemplate( "hellosite.vm" );

  q里Q初始化环境Qƈ数据放入环?BR>
/* create a context and add data */

VelocityContext context = new VelocityContext();

context.put("name", "Eiffel Qiu");

context.put("site", "http://www.eiffelqiu.com");

  其他代码比较固定Q但是也非常重要Q但是对于每个应用来说写法都很相同:
q是初始?Velocity 模板引擎

/* first, get and initialize an engine */

VelocityEngine ve = new VelocityEngine();
ve.init();

  q是用来环境变量和输出部分l合?BR>
StringWriter writer = new StringWriter();
t.merge( context, writer );
/* show the World */
System.out.println( writer.toString() );

  CQ这在将来的 servlet 应用中会有所区别Q因为网输出ƈ不和命o行输出相同,如果用于|页输出Q将q不通过 System.out 输出。这会在以后的教E中l大家解释的?BR>
那让我来ȝ一?Velocity 真正的工作原理:
  Velocity 解决了如何在 Servlet 和网之间传递数据的问题Q当然这U传输数据的机制是在 MVC 模式上进行的Q也是View ?Modle , Controller 之间怺独立工作Q一方的修改不媄响其他方变动Q他们之间是通过环境变量QContextQ来实现的,当然双方|页制作一方和后台E序一方要怺U定好对所传递变量的命名U定Q比如上个程序例子中?site, name 变量Q它们在|页上就?$name ,$site 。这样只要双方约定好了变量名字,那么双方可以独立工作了。无论页面如何变化,只要变量名不变,那么后台E序无需改动Q前台网也可以Lq制作h员修攏V这是 Velocity 的工作原理?BR>
  你会发现单变量名通常无法满|页制作昄数据的需要,比如我们l常会@环显CZ些数据集Q或者是Ҏ一些数据的值来军_如何昄下一步的数据Q?Velocity 同样提供了@环,判断的简单语法以满|页制作的需要。Velocity 提供了一个简单的模板语言以供前端|页制作人员使用Q这个模板语a_单(大部分懂?javascript 的h可以很快掌握,其实它比 javascript 要简单的多)Q当然这U简单是L的,因ؓ它不需要它什么都能做Q?View 层其实不应该包含更多的逻辑QVelocity 的简单模板语法可以满你所有对面昄逻辑的需要,q通常已经_了,q里不会发生?jsp 那样因ؓ一个无限@环语句而毁掉系l的情况Qjsp 能做很多事情QSun 在制?Jsp 1.0 标准的时候,没有及时的限定程序员?jsp 插入代码逻辑Q得早期的jsp 代码更象?php 代码Q它虽然强大Q但是对昄层逻辑来说Qƈ不必要,而且会 MVC 三层的逻辑l构发生h?BR>
我的|站Q?http://www.eiffelqiu.com
EmailQ?eiffelqiu@163.com
希望和大家交?BR>
出处Q牧h手记

]]>
velocity 的介l?------from matrix jdyaohttp://m.tkk7.com/jackybu/articles/8802.html?/dc:creator>?/author>Sat, 30 Jul 2005 14:26:00 GMThttp://m.tkk7.com/jackybu/articles/8802.htmlhttp://m.tkk7.com/jackybu/comments/8802.htmlhttp://m.tkk7.com/jackybu/articles/8802.html#Feedback0http://m.tkk7.com/jackybu/comments/commentRss/8802.htmlhttp://m.tkk7.com/jackybu/services/trackbacks/8802.htmlVelocity 是如何工作的呢? 虽然大多 Velocity 的应用都是基?Servlet 的网制作。但是ؓ了说?Velocity 的用,我决定采用更通用?Java application 来说明它的工作原理?BR>
  g所有语a教学的开头都是采?HelloWorld 来作为第一个程序的CZ。这里也不例外?BR>
  M Velocity 的应用都包括两个斚w:
  W一是: 模板制作Q在我们q个例子中就?hellosite.vm:
  它的内容如下Q虽然不是以 HTML ZQ但是这很容易改成一?html 的页面)

Hello $name! Welcome to $site world!

  W二?Java E序部分Q?BR>  下面?Java 代码

import java.io.StringWriter;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;

public class HelloWorld
{
public static void main( String[] args )
throws Exception
{
/* first, get and initialize an engine */

VelocityEngine ve = new VelocityEngine();
ve.init();

/* next, get the Template */

Template t = ve.getTemplate( "hellosite.vm" );

/* create a context and add data */

VelocityContext context = new VelocityContext();

context.put("name", "Eiffel Qiu");

context.put("site", "http://www.eiffelqiu.com");

/* now render the template into a StringWriter */

StringWriter writer = new StringWriter();

t.merge( context, writer );

/* show the World */

System.out.println( writer.toString() );
}
}

两个文件放在同一个目录下Q编译运行,l果是:

Hello Eiffel Qiu! Welcome to http://www.eiffelqiu.com world

  Z保证q行利Q请?Velocity 的网?http://jakarta.apache.org/velocity/ 上下?Velocity 的运行包Q将其中?Velocity Jar 包的路径攑֜pȝ?Classpath 中,q样可以编译和q行以上的程序了?BR>
出处Q牧h手记

]]>
վ֩ģ壺 99þùۺϾƷ| ޹Ѽһ| aѹۿƵ| Ѱββ8x| AVþþþվ| ҴýһAV| ŮݽƵѿ| 뿨ͨҰ| ëƬƵ| ˳վ߹ۿ| һ߹ۿ| պ| Ʒ߹ۿѲ| 99reƵƷȫ| þþþavר| ƷþþþþĻ | ŷ| ߹ۿ˳վҹ| ޾ƷþþþþͼƬ| վavƬ| 91۲˽˳ӰԺ| ƷһI6| Ļþһ| պƷһ| av߹ۿһ| ޳˻ɫ| ƬƵ| ŮվƵ| þþwwwëƬ| ˾޾ƷӰԺ߹ۿ | պѸ岥| AVҹƷһ| Ůվ91ɫ| ޾Ʒ߲| պӰ| aëƬa | av޽վ| ޾ƷþþþþͼƬ | ƬƵ| һëƬһëƬëƬ| ޹ƷþѾ|