Velocity是一個基於Java的模版引擎__Java

來源:互聯網
上載者:User

 Velocity是一個基於Java的模版引擎。它允許web頁面設計者引用Java代碼中定義的方法。web設計者能夠和Java程式員並行的工作來開發MVC模式的web網站,這意味著web頁面設計者能夠只關注建立設計良好的網站,而程式員能夠只關注編寫頂尖的代碼。Velocity將Java代碼從web頁面中分離出來,使得web網站在長期的運行中具有更好的可維護性。

        Velocity能夠用來建立web頁面,SQL,PostScript和其他能夠由模版輸出的代碼。它能夠單獨使用來產生原始碼或者報告,也可以和其他的系統整合。

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

先做一個最簡單的Velocity開發例子,讓大家看看Velocity是怎樣工作的:

1、建立1個檔案,檔案名稱為:hellovelocity.vm,即velocity模版(其實和html一樣),內容:

<html>

<title>Hello Velocity</title>

<body>

Welcome $name to Javayou.com!

today is $date.

</body>

</html>

2、建立1個java檔案,HelloVelocity.java,內容:

package com.javayou.velocity;

import java.io.StringWriter;

import java.util.*;

import org.apache.velocity.app.VelocityEngine;

import org.apache.velocity.Template;

import org.apache.velocity.VelocityContext;

/**

* @author Liang.xf 2004-12-14

*/

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());

}

}

3、在http://jakarta.apache.org/site/binindex.cgi上下載Velocity 1.4 zip,解壓後擷取velocity-1.4.jar,用它來編譯上面的類HelloVelocity.java。

4、把1上的hellovelocity.vm copy到啟動並執行目前的目錄下,運行HelloVelocity還需要其他類包,可以從下載後的velocity1.4.zip來,//velocity-1.4//build//lib,把commons-collections.jar、logkit-1.0.1.jar引入後運行java -cp .//bin; -Djava.ext.dirs=.//lib2 com.javayou.velocity.HelloVelocity,假設class編譯到.//bin目錄,而我們所需的類包放到.//lib2目錄內,運行結構如下:

<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這一層基本只用使用簡單的VTL(Velocity Template Language)來展示。這樣,Jsp豈不是不用了麼。是的,這樣的使用模式有點象早前的CGI方式:)由Velocity自動輸出代碼,並且Velocity在這方面的能力也很強,Turbine裡就採用了Velocity來產生很多代碼。

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

此外我們還需要注意的是Velocity特色的變數定義,如:$student.No、$student.Address,它有2層含義:第1種是如果student是hashtable,則將從hashtable中提取key為No和Address的值,另外第2種就是它有可能是調用方法,即上面2個變數將被轉換為student.getNo()和student.getAddress()。Velocity對在servlet中的java code返回的值有對象,還可以調用對象的方法,如$ student.getAddress()等等,在此就不一一舉例和深入了。

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

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

#set( $iAmVariable = "good!" )

Welcome $name to Javayou.com!

today is $date.

$iAmVariable

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

Welcome Liang to Javayou.com!

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>

把在例子中預先儲存在VelocityContext的List中的值列舉了出來,是不是很方便啊。僅僅只是用了#foreach($variable in xx) 而已,如果上面的List換成Hashtable,則可以用下面的文法:

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

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

#end

一點不覺得這些指令碼很複雜。

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

package com.javayou.velocity;

/**

* @author Liang.xf 2004-12-14

*/

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

這樣把list中Student的資料列印了出來,大功告成。這裡用了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代碼去除在Jsp(vm)外,如果光使用Struts(Servlet+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上使用國際化語言標籤的方式來做到,而每種語言採用不同的語言標籤庫的方式,引申到這裡,其實手工來做一樣可以做到,只不過需要稍加手工處理而已。

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

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

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

(關鍵字:Java, JSP, Servlet, template, 模板, Apache, Jakarta, Velocity)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.