hengheng123456789

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            297 Posts :: 68 Stories :: 144 Comments :: 0 Trackbacks
           

          Velocity Beginning

           

          作者: ahlie

           

          Velocity,名稱字面翻譯為:速度、速率、迅速,用在Web開發里,用過的人可能不多,大都基本知道和在使用Struts,到底VelocityStruts(TaglibTiles)是如何聯系?在技術上Velocity要比Struts Struts(TaglibTiles)先進,單從技術上考慮可以考慮Velocity;而Struts用的非常普遍,這樣的人才也很多,所以對于公司來說,選擇Struts的人才容易點。畢竟Velocity提供了一個很好的思維方式,給大家換了一種思考的方式。

           

          Velocity是一種Java模版引擎技術,該項目由Apache提出,由另外一種引擎技術Webmacro引深而來。那什么是官方的Velocity定義呢?Apache對它的定義是:一種基于Java的模板引擎,但允許任何人使用簡單而強大的模板語言來引用定義在Java代碼中的對象??梢栽?/span>http://jakarta.apache.org/velocity/index.html查找更多信息。

           

          其實Velocity就是MVC架構的一種實現,但它更多的是關注在ModelView之間,作為它們的橋梁。對于MVC的最流行架構Struts來說,相信大家都不陌生,很多開發人員已經大量在使用Struts架構,包括IBMWebsphere 5以上的管理平臺版本,Struts技術很好的實踐了MVC,它有效的減少Java代碼在ViewJsp)中的出現,但在ModelView之間還是依靠StrutsTaglib技術來實現,試想如果前臺開發的網頁設計師對Struts乃至Taglib不熟(相信也挺難熟的,包括后期的維護人員也一樣),將會對網頁設計師和前臺開發工程師的相互協作開發帶來很大的難度,現實開發中也還是存在這樣事實,網頁設計師和前臺開發之間的工作或多或少還是存在一定的耦合,怎樣最大限度的解決這個難題呢?還是讓我們來看看Velocity或者說這個概念吧。

           

          下面是一個簡單的Velocity例子:

           

          1、創建velocity模版(其實和html一樣),文件名為:hellovelocity.vm

           

          <html>

          <title>Hello Velocity</title>

          <body>

          Welcome $name to Javayou.com!

          today is $date.

          </body>

          </html>

           

          2、創建java文件,HelloVelocity.java

           

          package com.fasttalk. velocity;

          import java.io.StringWriter;

          import java.util.*;

          import org.apache.velocity.app.VelocityEngine;

          import org.apache.velocity.Template;

          import org.apache.velocity.VelocityContext;

           

          public class HelloVelocity {

          public static void main(String[] args) throws Exception {

          //初始化并取得Velocity引擎

          VelocityEngine ve = new VelocityEngine();

          ve.init();

          //取得velocity的模版

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

          //取得velocity的上下文context

          VelocityContext context = new VelocityContext();

          //把數據填入上下文

          context.put("name", "Liang");

          context.put("date", (new Date()).toString());

          //為后面的展示,提前輸入List數值

          List temp = new ArrayList();

          temp.add("1");

          temp.add("2");

          context.put("list", temp);

          //輸出流

          StringWriter writer = new StringWriter();

          //轉換輸出

          t.merge(context, writer);

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

          }

          }

           

          http://jakarta.apache.org/site/binindex.cgi上下載Velocity 1.4 zip

           

          4、把1上的hellovelocity.vm copy到運行的當前目錄下,運行結構如下:

           

          <html>

          <title>Hello Velocity</title>

          <body>

          Welcome Liang to Javayou.com!

          today is Tue Dec 14 19:26:37 CST 2004.

          </body>

          </html>

           

          以上是最簡單的運行結果,怎么樣,知道個大概吧,模版hellovelocity.vm里的2個定義變量$name$date分別被context.put("name", "Liang")context.put("date", (new Date()).toString())所設的值替代了。

           

          由此看來業務流程處理包括業務結果基本在model這層全部解決,而view這一層基本只用使用簡單的VTLVelocity Template Language)來展示。這樣,Jsp豈不是不用了么?是的,這樣的使用模式有點象早前的CGI方式:)由Velocity自動輸出代碼,并且Velocity在這方面的能力也很強,Turbine里就采用了Velocity來產生很多代碼。

           

          Velocity中,變量的定義都是使用“$”開頭的,$作為Velocity的標識符。字母、數字、中劃和下劃線都可以作為Velocity的定義變量。

           

          還需要注意的是Velocity特色的變量定義,如:$student.No、$student.Address,它有2層含義:

           

          l       1種是如果studenthashtable,則將從hashtable中提取keyNoAddress的值,

           

          l       另外第2種就是它有可能是調用方法,即上面2個變量將被轉換為student.getNo()student.getAddress()。

           

          Velocity對在servlet中的java code返回的值有對象,還可以調用對象的方法,如$ student.getAddress()等等,在此就不一一舉例和深入了。

           

          上面的例子只是簡單的舉例,現在當然不少人已經不滿足這樣的例子了,實際的應用中我們還常常需要作些選擇性展示和列舉一些迭代數據,如List列表,當然Velocity(具體來說應該是VTL模版語言)也支持這項功能,此外還支持其他一些常用的展示,如模版內部的變量(如Jsp內的變量),還有強大一些的如創建宏以實現自動化,讓我們繼續接著往下看吧。

           

          我們還是使用上面的例子,把模版hellovelocity.vm中的內容改為:

           

          #set( $iAmVariable = "good!" )

          Welcome $name to csdn.net!

          today is $date.

          $iAmVariable

           

          重新執行上面的運行命令,結果:

           

          Welcome Liang to csdn.net!

          today is Tue Dec 14 22:44:39 CST 2004.

          good!

           

          可以看得模版中的變量定義為# set開頭的語句,不是很難理解,執行后模版中的變量$iAmVariable都轉換成定義的值:good!

           

          再來看看簡單的選擇,把模版hellovelocity.vm中的內容改為:

           

          #set ($admin = "admin")

          #set ($user = "user")

          #if ($admin = = $user)

          Welcome admin!

          #else

          Welcome user!

          #end

           

          執行運行命令,結果:

           

          Welcome user!

           

          可以看到判斷語句只是簡單的#if ()、#else、#end,不是很復雜。

           

          接著繼續來看看迭代數據吧,把模版hellovelocity.vm中的內容改為:

           

          #foreach( $product in $list )

          <li>$product</li>

          #end

           

          執行運行命令,結果:

           

          <li>1</li>

           

          <li>2</li>

           

          把在例子中預先保存在VelocityContextList中的值列舉了出來,是不是很方便?。績H僅只是用了#foreach$variable in xx 而已,如果上面的List換成Hashtable,則可以用下面的語法:

           

          #foreach($key in $hashVariable.keySet() )

          <li> $key ‘s value: $ hashVariable.get($key) </li>

          #end

           

          一點不覺得這些腳本很復雜。

           

          還有不少人還會問,如果是javabean怎么辦?好的,我們增加一個bean

           

          package com.fasttalk.velocity;

           

          public class Student {

          //注意class的屬性是public

          public String no = "";

          public String address = ""

          public Student(String _no, String _address) {

          no = _no;

          address = _address;

          }

          public String getAddress() {

          return address;

          }

          public void setAddress(String address) {

          this.address = address;

          }

          public String getNo() {

          return no;

          }

          public void setNo(String no) {

          this.no = no;

          }

          }

           

          這個Student是實足的javabean,或者說是data bean,常見的用來裝載數據的類,然后我們修改HelloVelocity.java,把:

           

          temp.add("1");

           

          temp.add("2");

           

          替換成:

           

          temp.add(new Student("123", "Guangzhou"));

          temp.add(new Student("456", "Zhuhai"));

           

          再把hellovelocity.vm的內容改為:

           

          #foreach ($s in $students)

          <$velocityCount> Address: $s.address

          #end

           

          重新編譯和執行運行命令,結果如下:

           

          <1> Address: Guangzhou

          <2> Address: Zhuhai

           

          這樣把listStudent的數據打印了出來,大功告成!這里用了Velocity的內建變量$velocityCount,指的是默認的列舉序號,從1開始,也可以改成0開始,但需要在Velocity.properties中更改,Velocity.properties位于velocity-1.4.jar包內的目錄org/apache/velocity/runtime/defaults 下。

           

          再復雜一些的迭代怎么處理呢?我們看看下面的模版例子就清楚了:

           

          #foreach ($element in $list)

          -- inner foreach --

          #foreach ($element in $list)

          This is $element.

          $velocityCount

          #end

          -- inner foreach --

          -- outer foreach --

          This is $element.

          $velocityCount

          -- outer foreach --

          #end

           

          看出來了吧,Velocity是支持標簽嵌套的,這個可是很強大的功能,這里就不深入演示了,如果有興趣,自己試試吧。

           

          其實,稍為深入思考剛剛我們舉的例子,就已經可以看出來,Velocity的用處在哪里?即Servlet + Velocity的模式,另外,還記得我們早期Jsp開發的模式Jsp+JavaBean嗎?在這里,我們更改為Servlet+JavaBean+Velocity,想想,是不是已經替代了Jsp+JavaBean,并更徹底的把Java代碼去除在Jspvm)外,如果光使用StrutsServlet+Jsp),那么帶來的代價是Java代碼總或多或少出現在Jsp上,即使可以做到不出現Java代碼,但做過復雜架構系統的開發者都知道,代價也是很昂貴的,并且在可維護性、和網頁設計師的集成開發上存在一定的困難,所以我們在這里能感覺到,Servlet+JavaBean+Velocity的模式較好的實現了OOD的概念。而在效率上,大家也不用擔心,此種結合方式比Servlet+Jsp的方式要高效一些。

           

          愿意了解Velocity的人應該不少,但真正實用到項目的,也許不多(還是有些項目在使用,如Jute),畢竟和Jsp比起來,Jsp更標準、更廣泛使用和有不少開發工具已經支持Jsp開發。但Velocity的功能不會僅僅局限在和Jsp競爭的局面,由上可看出它在自動代碼輸出方面功能很強,前面提到Turbine就是采用Velocity來生成很多代碼,你也可以稍加改動就可以做成代碼生成器,或其他模版生成上,都是很不錯的想法。

           

          好了,我們再來看看要深入Velocity來做項目,還需要注意的一些常見問題吧,首先是國際化的問題,

           

          Velocity本身支持模版的國際化編碼轉換,看看Velocity提供的方法:

           

          Public Template getTemplate (Stirng template, String encoding)

           

          由此推測這樣做其實不能徹底的做到國際化。

           

          最簡單的在Struts中國際化的概念,即在Jsp上使用國際化語言標簽的方式來做到,而每種語言采用不同的語言標簽庫的方式,引申到這里,其實手工來做一樣可以做到,只不過需要稍加手工處理而已。

           

          好在已經有人處理了上面所說問題,做成了Velocitytools: MessageTool,提供了變量text包含國際化標簽,這樣只需要簡單的編寫標簽代碼即可,如:$text.get(title),更多具體的內容還可在http://jakarta.apache.org/velocity/tools/struts/MessageTool.html 中了解。

           

          好了,基于Velocity的介紹我們就說這么多,再說說其他引伸方面的內容吧。有人評論Velocity不是標準的MVC結構,沒錯,剛開始我們就說過Velocity只是ModelView之間的良好結合,只是個好的模版引擎,畢竟還沒有形成MVC三者良好的結合。好在Apache又基于StrutsVelocity的結合,推出了VelocityStruts,這部分的陳述我們可以在后面的專題里再推出,這里簡單介紹它的概念,它是在Struts的結構上,在業務邏輯處理的Action后,把業務流程轉向基于Velocity的顯示層,從而代替Jsp作為View層。以上我們也看到了所舉的例子基本上只是基于原理和演示,沒有和Web開發緊密結合起來,這方面內容我們在講述VelocityStruts的內容時再來結合吧。

           

          談到Velocity,在這里要順便提提FreeMarkerFreeMarker也是一種模版引擎,和Velocity功能基本類似,都是簡單和輕量級的工具,但功能上較Velocity有不少增強的地方,這我們也在以后再來深入了解吧。

          posted on 2007-05-29 18:09 哼哼 閱讀(287) 評論(0)  編輯  收藏 所屬分類: JAVA-Common
          主站蜘蛛池模板: 仪陇县| 广昌县| 蓬莱市| 金阳县| 连州市| 四平市| 波密县| 抚宁县| 界首市| 张家界市| 乌什县| 利津县| 垦利县| 惠安县| 岳阳县| 龙川县| 钟山县| 陆河县| 兴山县| 青田县| 海淀区| 彩票| 保山市| 应城市| 甘孜县| 宣城市| 元阳县| 睢宁县| 治多县| 景德镇市| 彩票| 衡阳市| 临西县| 扬州市| 龙川县| 重庆市| 卢湾区| 武城县| 平远县| 吉首市| 蕉岭县|