基于 Java 的網(wǎng)站開發(fā),很多人都采用 JSP 作為前端網(wǎng)頁制作的技術(shù),尤其在是國(guó)內(nèi)。這種技術(shù)通常有一些問題,我試想一下我們是怎樣開發(fā)網(wǎng)站的,通常有幾種方法: 1:功能確定后,由美工設(shè)計(jì)網(wǎng)頁的UI(界面)部分,然后由程序員在其上加入代碼顯示邏輯(比如循環(huán),判斷顯示數(shù)據(jù)結(jié)果)。也就是通常的 jsp 頁面制作,當(dāng)然這部分可以由美工完成模板,然后由 jsp 工程師再繼續(xù)以它為原型創(chuàng)建相應(yīng)的 jsp 頁面。 2:功能確定后,由美工設(shè)計(jì)網(wǎng)頁的UI(界面)部分,然后由網(wǎng)頁制作人員在其上加入代碼顯示邏輯(比如循環(huán),判斷顯示數(shù)據(jù)結(jié)果),在這一步的 jsp 頁面制作中,網(wǎng)頁制作人員(通常只懂得 javascript 和 html )在工程師的指導(dǎo)下學(xué)會(huì)如何嵌入 jsp taglib 標(biāo)記,然后以美工的模板為原型制作 jsp 網(wǎng)頁。 顯然后面一種方式要比前面一種方式分工明確,然后在很多小公司,或者項(xiàng)目很急的情況下,jsp 網(wǎng)頁制作和后臺(tái)程序開發(fā)都是同一個(gè)人。這樣無疑加大了程序員的負(fù)擔(dān)。 后一種情況雖然比前面的好,但是它有兩個(gè)缺點(diǎn): 一:網(wǎng)頁制作人員必須學(xué)會(huì)如何使用 jsp taglib 的使用,這無疑加大了網(wǎng)頁制作人員的負(fù)擔(dān)。二:如果頁面因?yàn)榭蛻舻囊髲男略O(shè)計(jì),那么無論那種情況網(wǎng)頁制作人員都要從新將顯示邏輯從新嵌入 jsp 網(wǎng)頁。 在這方面, jsp 做的并不好,雖然從性能角度和 taglib 的使用上來說,它比 php 和 asp 要強(qiáng)很多, 但是它在設(shè)計(jì)上很類似 php 這種服務(wù)器頁面語言,也就是在頁面中嵌入腳本語言的技術(shù),雖然它比傳統(tǒng)的基于 CGI 的腳本語言的開發(fā)模式速度快,但是它將后臺(tái)程序邏輯與頁面顯示混淆了,所以從這個(gè)角度來說, 它是一種不太良好的設(shè)計(jì)。想想看,你看到的眾多 php 程序是怎么樣子的吧,在一堆 .php 文件中,你已經(jīng)分不清楚那些是后臺(tái)程序,那些只是用來顯示頁面的程序。 現(xiàn)在更多的網(wǎng)站制作采用一種 MVC 模式,也就是將網(wǎng)站制作工作分工,分別為M(Model, 模型),V(View 視圖),C(Controller 控制器). M(Model, 模型)也就是后臺(tái)的事務(wù)邏輯,真正處理事務(wù)的代碼,商業(yè)邏輯等等。他們是整個(gè)網(wǎng)站最重要的工作部分,通常這部分代碼相對(duì)來說比較穩(wěn)定,不經(jīng)常變動(dòng),就是有所變動(dòng)也不會(huì)對(duì)前端的頁面有什么影響。 V(View 視圖): 也就是網(wǎng)頁的顯示部分,這個(gè)部分接受來自后臺(tái)程序的結(jié)果或數(shù)據(jù),進(jìn)行顯示,但是這個(gè)部分通常是變化比較大的部分,比如網(wǎng)站的界面更新是經(jīng)常要要作的事情,每隔一段時(shí)間更新網(wǎng)頁風(fēng)格就會(huì)造成 View 視圖部分的大量更改工作。 C(Controller 控制器). 在視圖和模型之間傳遞控制,并根據(jù)要求調(diào)用相應(yīng)的視圖顯示模型返回的數(shù)據(jù),主要負(fù)責(zé)調(diào)度工作。 這種職責(zé)的分工到底有什么好處呢,它簡(jiǎn)化了軟件開發(fā)過程中所有相關(guān)人員的工作, 使得不同的部分的修改通常不會(huì)影響的其他部分的工作,比如,我修改了后臺(tái)某些程序的算法,并不影響前臺(tái)的頁面顯示,前臺(tái)頁面修改不影響后臺(tái)程序的開發(fā)。這種分工合作比起 jsp 混淆代碼邏輯和顯示層的做法要好的多。 所以越來越多的國(guó)外程序員在不斷提出替代 jsp 的方案,在眾多方案中, 一種基于 java 模板引擎的技術(shù)脫穎而出,最為著名的是 Velocity 和 Webmacro 兩種模板技術(shù)。 模板引擎的設(shè)計(jì)思想最早是有 webmacro 提出的, 后來應(yīng)用在一個(gè)著名的搜索引擎 www.altavista.com 上, 這種思想漸漸被 Apache 開發(fā)小組所采用,并作為一個(gè)子項(xiàng)目被提出來,這就是現(xiàn)在的 Velocity。模板引擎與MVC中視圖這一部分的關(guān)系更為密切。它是經(jīng)常作為一種 jsp 的替代技術(shù)出現(xiàn)在國(guó)外的一些論壇上的。但是 Velocity 可以應(yīng)用在任何需要格式化數(shù)據(jù)顯示的 java 程序中。 那么 Velocity 到底是什么呢?它的官方解釋是: "Velocity 是一種基于 java 的模板引擎,它允許任何人使用簡(jiǎn)單而強(qiáng)大的模板語言來引用定義在 java 代碼中的對(duì)象" 你可能因?yàn)橄旅鎺追N原因而使用 Velocity: 1:它很容易集成在各種各樣的程序領(lǐng)域中。 2:它為網(wǎng)頁制作人員提供了一種清晰而又簡(jiǎn)單的語法 3:因?yàn)槟0搴痛a是分離的,所以你可以分別獨(dú)立的開發(fā)和維護(hù)它們。 4:Velocity 引擎可以很容易的集成到一些 Java 運(yùn)行環(huán)境,特別是 Servlet. 5:Velocity 使得模板可以訪問任何環(huán)境對(duì)象中的共有方法。 Velocity 的強(qiáng)大之處在于它嚴(yán)格的區(qū)分程序開發(fā)功能的職責(zé)劃分。 它限制模板可能訪問的對(duì)象(也就是后臺(tái)程序允許它得到的對(duì)象)來實(shí)現(xiàn)這一點(diǎn)。這意味著,網(wǎng)頁設(shè)計(jì)人員可以只把精力放在數(shù)據(jù)的顯示部分(View 視圖)而程序員則只要關(guān)注如何寫好程序的控制層(Controller,控制器)和商業(yè)邏輯和數(shù)據(jù)管理(模型 Model), 這就是 MVC 開發(fā)模式。MVC 現(xiàn)在已經(jīng)是廣泛接受的一種開發(fā)模式,它簡(jiǎn)化了開發(fā)和日益復(fù)雜的應(yīng)用和維護(hù)工作。 Velocity 最擅長(zhǎng)做哪些方面的工作呢? 1: 基于 servlet 的網(wǎng)站制作 2: Java 和 Sql 代碼生成 3: XML 處理和轉(zhuǎn)換 4: 文字處理,比如生成 TRF 文件。 不過 Velocity 用的最多的還是在基于 Java servlet 的網(wǎng)頁程序中作生成網(wǎng)頁的引擎,以替代 JSP 等技術(shù)。 除了比較容易使用外, 它提供了強(qiáng)大的模板語言以顯示和操作數(shù)據(jù),但是不是生成數(shù)據(jù),這點(diǎn)很重要, 因?yàn)檫@個(gè)工作應(yīng)該是程序邏輯的部分。 Velocity 非常適合在 J2EE (Java 2 Platform, Enterprise Edition) 的網(wǎng)站開發(fā)中充當(dāng)替代 jsp 做輸出頁面的技術(shù)工作,雖然 JSP 包含在 j2ee 的規(guī)范中,其實(shí) j2ee 本身并不需要 jsp . Velocity 是如何工作的呢? 雖然大多 Velocity 的應(yīng)用都是基于 Servlet 的網(wǎng)頁制作。但是為了說明 Velocity 的使用,我決定采用更通用的 Java application 來說明它的工作原理。 似乎所有語言教學(xué)的開頭都是采用 HelloWorld 來作為第一個(gè)程序的示例。這里也不例外。 任何 Velocity 的應(yīng)用都包括兩個(gè)方面: 第一是: 模板制作,在我們這個(gè)例子中就是 hellosite.vm: 它的內(nèi)容如下(雖然不是以 HTML 為主,但是這很容易改成一個(gè) html 的頁面) Hello $name! Welcome to $site world! 第二是 Java 程序部分: 下面是 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."); /* now render the template into a StringWriter */ StringWriter writer = new StringWriter(); t.merge( context, writer ); /* show the World */ System.out.println( writer.toString() ); } } 將兩個(gè)文件放在同一個(gè)目錄下,編譯運(yùn)行,結(jié)果是: Hello Eiffel Qiu! Welcome to http://www. world 為了保證運(yùn)行順利,請(qǐng)從 Velocity 的網(wǎng)站 http://jakarta./velocity/ 上下載 Velocity 的運(yùn)行包,將其中的 Velocity Jar 包的路徑放在系統(tǒng)的 Classpath 中,這樣就可以編譯和運(yùn)行以上的程序了。 這個(gè)程序很簡(jiǎn)單,但是它能讓你清楚的了解 Velocity 的基本工作原理。程序中其他部分基本上很固定,最主要的部分在以下代碼 這里 Velocity 獲取模板文件,得到模板引用 /* next, get the Template */Template t = ve.getTemplate( "hellosite.vm" ); 這里,初始化環(huán)境,并將數(shù)據(jù)放入環(huán)境 /* create a context and add data */VelocityContext context = new VelocityContext();context.put("name", "Eiffel Qiu");context.put("site", "http://www."); 其他代碼比較固定,但是也非常重要,但是對(duì)于每個(gè)應(yīng)用來說寫法都很相同: 這是初始化 Velocity 模板引擎 /* first, get and initialize an engine */VelocityEngine ve = new VelocityEngine();ve.init(); 這是用來將環(huán)境變量和輸出部分結(jié)合。 StringWriter writer = new StringWriter();t.merge( context, writer );/* show the World */System.out.println( writer.toString() ); 記住,這在將來的 servlet 應(yīng)用中會(huì)有所區(qū)別,因?yàn)榫W(wǎng)頁輸出并不和命令行輸出相同,如果用于網(wǎng)頁輸出,將并不通過 System.out 輸出。這會(huì)在以后的教程中給大家解釋的。 那讓我來總結(jié)一下 Velocity 真正的工作原理: Velocity 解決了如何在 Servlet 和 網(wǎng)頁之間傳遞數(shù)據(jù)的問題,當(dāng)然這種傳輸數(shù)據(jù)的機(jī)制是在 MVC 模式上進(jìn)行的,也就是View 和 Modle , Controller 之間相互獨(dú)立工作,一方的修改不影響其他方變動(dòng),他們之間是通過環(huán)境變量(Context)來實(shí)現(xiàn)的,當(dāng)然雙方網(wǎng)頁制作一方和后臺(tái)程序一方要相互約定好對(duì)所傳遞變量的命名約定,比如上個(gè)程序例子中的 site, name 變量,它們?cè)诰W(wǎng)頁上就是 $name ,$site 。 這樣只要雙方約定好了變量名字,那么雙方就可以獨(dú)立工作了。 無論頁面如何變化,只要變量名不變,那么后臺(tái)程序就無需改動(dòng),前臺(tái)網(wǎng)頁也可以任意由網(wǎng)頁制作人員修改。這就是 Velocity 的工作原理。 你會(huì)發(fā)現(xiàn)簡(jiǎn)單變量名通常無法滿足網(wǎng)頁制作顯示數(shù)據(jù)的需要,比如我們經(jīng)常會(huì)循環(huán)顯示一些數(shù)據(jù)集,或者是根據(jù)一些數(shù)據(jù)的值來決定如何顯示下一步的數(shù)據(jù), Velocity 同樣提供了循環(huán),判斷的簡(jiǎn)單語法以滿足網(wǎng)頁制作的需要。Velocity 提供了一個(gè)簡(jiǎn)單的模板語言以供前端網(wǎng)頁制作人員使用,這個(gè)模板語言足夠簡(jiǎn)單(大部分懂得 javascript 的人就可以很快掌握,其實(shí)它比 javascript 要簡(jiǎn)單的多),當(dāng)然這種簡(jiǎn)單是刻意的,因?yàn)樗恍枰裁炊寄茏觯?View 層其實(shí)不應(yīng)該包含更多的邏輯,Velocity 的簡(jiǎn)單模板語法可以滿足你所有對(duì)頁面顯示邏輯的需要,這通常已經(jīng)足夠了,這里不會(huì)發(fā)生象 jsp 那樣因?yàn)橐粋€(gè)無限循環(huán)語句而毀掉系統(tǒng)的情況,jsp 能做很多事情,Sun 在制定 Jsp 1.0 標(biāo)準(zhǔn)的時(shí)候,沒有及時(shí)的限定程序員在 jsp 插入代碼邏輯,使得早期的jsp 代碼更象是 php 代碼,它雖然強(qiáng)大,但是對(duì)顯示層邏輯來說,并不必要,而且會(huì)使 MVC 三層的邏輯結(jié)構(gòu)發(fā)生混淆。 |
|