Velocity,名稱字面翻譯爲:速度、速率、迅速,用在Web開發裏,用過的人可能很少,大都基本知道和在使用Struts,到底Velocity和Struts(Taglib和Tiles)是如何聯繫?在技術上Velocity要比Struts Struts(Taglib和Tiles)先進,單從技術上考慮能夠考慮Velocity;而Struts用的很是廣泛,這樣的人才也不少,因此對於公司來講,選擇Struts的人才容易點。畢竟Velocity提供了一個很好的思惟方式,給你們換了一種思考的方式。html
Velocity是一種Java模版引擎技術,該項目由Apache提出,由另一種引擎技術Webmacro引深而來。那什麼是官方的Velocity定義呢?Apache對它的定義是:一種基於Java的模板引擎,但容許任何人使用簡單而強大的模板語言來引用定義在Java代碼中的對象。目前最新的版本是1.4,能夠在http://jakarta.apache.org/velocity/index.html查找更多信息。java
其實Velocity就是MVC架構的一種實現,但它更多的是關注在Model和View之間,做爲它們的橋樑。對於MVC的最流行架構Struts來講,相信你們都不陌生,不少開發人員已經大量在使用Struts架構,包括IBM的Websphere 5以上的管理平臺版本,Struts技術很好的實踐了MVC,它有效的減小Java代碼在View(Jsp)中的出現,但在Model和View之間仍是依靠Struts的Taglib技術來實現,試想若是前臺開發的網頁設計師對Struts乃至Taglib不熟(相信也挺難熟的,包括後期的維護人員也同樣),將會對網頁設計師和前臺開發工程師的相互協做開發帶來很大的難度,現實開發中也仍是存在這樣事實,網頁設計師和前臺開發之間的工做或多或少仍是存在必定的耦合,怎樣最大限度的解決這個難題呢?仍是讓咱們來看看Velocity或者說這個概念吧。apache
下面是一個簡單的Velocity例子:架構
一、建立velocity模版(其實和html同樣),文件名爲:hellovelocity.vmapp
<html>
<title>Hello Velocity</title>
<body>
Welcome $name to Javayou.com!
today is $date.
</body>
</html>工具
二、建立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;this
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 zipspa
四、把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這一層基本只用使用簡單的VTL(Velocity Template Language)來展現。這樣,Jsp豈不是不用了麼?是的,這樣的使用模式有點象早前的CGI方式:)由Velocity自動輸出代碼,而且Velocity在這方面的能力也很強,Turbine裏就採用了Velocity來產生不少代碼。
在Velocity中,變量的定義都是使用「$」開頭的,$做爲Velocity的標識符。字母、數字、中劃和下劃線均可以做爲Velocity的定義變量。
還須要注意的是Velocity特點的變量定義,如:$student.No、$student.Address,它有2層含義:
l 第1種是若是student是hashtable,則將從hashtable中提取key爲No和Address的值,
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>
把在例子中預先保存在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.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
這樣把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有很多加強的地方,這咱們也在之後的文章中再來深刻了解吧。