MVC表示層框架——Velocity技術

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。

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

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

其實Velocity就是MVC架構的一種實現,但它更多的是關注在Model和View之間,作為它們的橋梁。對于MVC的最流行架構Struts來說,相信大家都不陌生,很多開發人員已經大量在使用Struts架構,包括IBM的Websphere 5以上的管理平臺版本,Struts技術很好的實踐了MVC,它有效的減少Java代碼在View(Jsp)中的出現,但在Model和View之間還是依靠Struts的Taglib技術來實現,試想如果前臺開發的網頁設計師對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這一層基本只用使用簡單的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有不少增強的地方。

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/451801.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/451801.shtml
英文地址,請注明出處:http://en.pswp.cn/news/451801.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

redis的配置文件

redis的配置文件 之前在實習的時候才開始接觸redis&#xff0c;隨著對redis的理解加深&#xff0c;才慢慢明白它的強大&#xff0c;也逐漸對他的配置有了一定的了解。下面就分享給大家&#xff0c;以便日后查看。 位置 redis的配置文件名為redis.conf在它的安裝目錄下。 參數說…

你的代碼(軟件)安全嗎?【信息圖】

2011年安全事件層出不窮&#xff0c;幾乎可以稱為“黑客年”。以前黑客通常是利用程序漏洞來造成破壞&#xff0c;令網站陷入尷尬的境地&#xff0c;但如今他們卻是為了竊取數據、IP地址&#xff0c;或者通過在網站中植入木馬將惡意軟件安裝到訪客的電腦里&#xff0c;更有甚者…

20--兩個數組的交集

文章目錄1.問題描述2.代碼詳情1.問題描述 給定兩個數組&#xff0c;編寫一個函數來計算它們的交集。 示例 1&#xff1a; 輸入&#xff1a;nums1 [1,2,2,1], nums2 [2,2] 輸出&#xff1a;[2] 示例 2&#xff1a; 輸入&#xff1a;nums1 [4,9,5], nums2 [9,4,9,8,4] 輸…

MD5密碼加密

using System; using System.Security.Cryptography; using System.Text; namespace DimoNetwork.Common.DEncrypt { public enum MD5ResultMode : byte { Strong 0, Weak 1 } /// /// 在應用程序中定義用于單向加密文本的方法 /// public class TextEncrypt { private TextE…

跳出IT運維怪圈 看南方報業如何主動出擊

雖說世界上沒有一勞永逸的事情&#xff0c;不過借助某些方案&#xff0c;IT運維倒可做到事半功倍。近日&#xff0c;南方報業傳媒集團采用新華三智動遠程運維服務解決方案&#xff0c;利用7*24級別安仔的桌面服務&#xff0c;實現IT運維智能化、自動化管理&#xff0c;有效保障…

ORA-01841: (完整) 年份值必須介于 -4713 和 +9999 之間, 且不為 0情況解決

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1. 報錯&#xff1a;ORA-01841: (完整) 年份值必須介于 -4713 和 9999 之間, 且不為 0 2. 我的sql是&#xff1a; <!-- 查詢 推薦下載…

網絡傳輸與加密

談到網絡&#xff0c;就必然會涉及網絡安全。但“安全”這個事情&#xff0c; 一下子就會讓人聯想到黑客&#xff0c;進而把“安全”這個事情無限放大為各種高大上、神秘莫測、不可知。這不是一個engineer應有的態度&#xff08;《一次艱難debug的反思》&#xff09;。 要討論網…

21--最小棧

文章目錄1.問題描述2. 代碼詳情1.問題描述 設計一個支持 push &#xff0c;pop &#xff0c;top 操作&#xff0c;并能在常數時間內檢索到最小元素的棧。 push(x) —— 將元素 x 推入棧中。 pop() —— 刪除棧頂的元素。 top() —— 獲取棧頂元素。 getMin() —— 檢索棧中的…

python讀取excel

1 import xlrd2 book xlrd.open_workbook(app_student.xls)3 sheet book.sheet_by_index(0)4 # sheet2 book.sheet_by_name(shee1)5 # print(sheet.cell(0,0).value) #指定sheet頁里面行和lie獲取數據6 # print(sheet.cell(1,0).value) #指定sheet頁里面行和lie獲取數據7 # …

Expected MultipartHttpServletRequest: is a MultipartResolver configured方案。

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1.報錯&#xff1a;Expected MultipartHttpServletRequest: is a MultipartResolver configured &#xff1f; 2.解決&#xff1a; a…

軟件開發中需要專職的 QA 嗎?

導讀&#xff1a;相信很多軟件開發企業都有專職 QA。然而&#xff0c;這些專職人員能否發揮其本身價值&#xff1f;我們是否需要專職的QA&#xff1f;針對這些問題&#xff0c;本文作者提出了他的看法。 以下為文章原文&#xff1a; 這個文章必然是有爭議的&#xff0c;我在我的…

【洛谷P1288】取數游戲II

取數游戲II 題目鏈接 顯然&#xff0c;由于一定有一個0&#xff0c;我們可以求出從初始點到0的鏈的長度 若有一條鏈長為奇數&#xff0c;則先手可以每次取完一條邊上所有的數&#xff0c; 后手只能取另一條邊的數&#xff0c;先手必勝&#xff1b; 反之若沒有奇數鏈&#xff0c…

22--刪除字符串中的所有相鄰重復項

文章目錄1. 題目要求2.代碼詳情1. 題目要求 給出由小寫字母組成的字符串 S&#xff0c;重復項刪除操作會選擇兩個相鄰且相同的字母&#xff0c;并刪除它們。 在 S 上反復執行重復項刪除操作&#xff0c;直到無法繼續刪除。 在完成所有重復項刪除操作后返回最終的字符串。答案保…

操作系統常考知識點總結(1)

1.什么是進程&#xff08;process&#xff09;和線程&#xff08;thread&#xff09;&#xff1f;有何區別&#xff1f; 1&#xff09;定義 進程是系統進行資源分配和調度的基本單位&#xff0c;線程是進程的一個實體&#xff0c;是cpu調度和分派的基本單位&#xff0c;是比進程…

jQuery上傳插件Uploadify使用Demo、本地上傳(ssm框架下)

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 效果&#xff1a; 1. jar包導入&#xff1a; <!-- 文件上傳組件 --><dependency><groupId>commons-fileupload</g…

P4313 文理分科 網絡流

其實也就卡了卡常&#xff0c;&#xff0c;&#xff0c; 先考慮沒有same_art和same_science 。 起點用art的流量連向每個點&#xff0c;該點再用science的流量連向終點&#xff0c;斷開哪邊相當于少了哪邊收益。 先全部收益加起來&#xff0c;再減去最小割即可。 那有same這些情…

23--有效的括號

文章目錄1.題目詳情2.代碼詳情1.題目詳情 給定一個只包括 ‘(’&#xff0c;’)’&#xff0c;’{’&#xff0c;’}’&#xff0c;’[’&#xff0c;’]’ 的字符串&#xff0c;判斷字符串是否有效。有效字符串需滿足&#xff1a; 左括號必須用相同類型的右括號閉合。 左括號…

11 步教你選擇最穩定的 MySQL 版本

MySQL開源數據庫有多個重要分支&#xff0c;目前擁有的分支分別為&#xff1a;MySQL Cluster、MySQL 5.1、MySQL 5.5、MySQL 6.2。每個分支都有著同樣的的MySQL數據庫版本&#xff0c;分別為&#xff1a;Development版本、Alpha版本、Beta版本、RC版本和GA版本。Development版本…