Servlet和JSP技術(shù)是用Java開發(fā)服務(wù)器端應(yīng)用的主要技術(shù),,是開發(fā)商務(wù)應(yīng)用表示端的標(biāo)準(zhǔn),。Java開發(fā)者喜歡使用它有多種原因,其一是對(duì)于已經(jīng)熟悉Java語(yǔ)言的開發(fā)者來(lái)說(shuō)這個(gè)技術(shù)容易學(xué)習(xí),;其二是Java把“一次編寫,,到處運(yùn)行”的理念帶入到Web應(yīng)用中,實(shí)現(xiàn)了“一次編寫,,到處實(shí)現(xiàn)”,。而且更為重要的是,,如果遵循一些良好的設(shè)計(jì)原則的話,就可以把表示和內(nèi)容相分離,,創(chuàng)造出高質(zhì)量的,、可以復(fù)用的、易于維護(hù)和修改的應(yīng)用程序,。比方說(shuō),,在HTML文檔中如果嵌入過(guò)多的Java代碼(scriptlet),就會(huì)導(dǎo)致開發(fā)出來(lái)的應(yīng)用非常復(fù)雜,、難以閱讀,、不容易復(fù)用,而且對(duì)以后的維護(hù)和修改也會(huì)造成困難,。事實(shí)上,,在CSDN的JSP/Servlet論壇中,經(jīng)??梢钥吹揭恍┨釂?,代碼很長(zhǎng),可以邏輯卻不是很清晰,,大量的HTML和Java代碼混雜在一起,,讓人看得一頭霧水。這就是隨意開發(fā)的弊端,。 如果你已經(jīng)基本了解JSP和Servlet的各項(xiàng)技術(shù)(最好也開發(fā)過(guò)一些Web應(yīng)用),,那么我們可以一起探討一下如何開發(fā)“好”的應(yīng)用的一些指導(dǎo)原則。我們首先對(duì)Servlet和JSP技術(shù)做一個(gè)瀏覽,。 Servlet和JSP概覽 早期的動(dòng)態(tài)網(wǎng)頁(yè)主要采用CGI(Common Gateway Interface,,公共網(wǎng)關(guān)接口)技術(shù),你可以使用不同的語(yǔ)言編寫CGI程序,,如VB,、C/C++或Delphi等。雖然CGI技術(shù)發(fā)展成熟且功能強(qiáng)大,,但由于編程困難,、效率低下、修改復(fù)雜等缺點(diǎn),,所以有逐漸被取代的趨勢(shì),。在所有的新技術(shù)中,JSP/Servlet具備更高效,、更容易編程,、功能更強(qiáng)、更安全和具有良好的可移植性,,因而被許多人認(rèn)為是未來(lái)最有發(fā)展前途的動(dòng)態(tài)網(wǎng)站技術(shù),。 與CGI相似,,Servlet支持請(qǐng)求/響應(yīng)模型。當(dāng)一個(gè)客戶向服務(wù)器遞交一個(gè)請(qǐng)求時(shí),,服務(wù)器把請(qǐng)求送給Servlet,,Servlet負(fù)責(zé)處理請(qǐng)求并生成響應(yīng),然后送給服務(wù)器,,再由服務(wù)器發(fā)送給客戶,。與CGI不同的是,Servlet沒有生成新的進(jìn)程,,而是與HTTP Server處于同一進(jìn)程中,。它通過(guò)使用線程技術(shù),減小了服務(wù)器的開銷,。Servlet處理請(qǐng)求的過(guò)程是這樣的:當(dāng)收到來(lái)自客戶端的請(qǐng)求后,,調(diào)用service方法,該方法中Servlet先判斷到來(lái)的請(qǐng)求是什么類型的(GET/POST/HEAD…),,然后調(diào)用相應(yīng)的處理方法(doGet/doPost/doHead…)并生成響應(yīng)。 別看這么復(fù)雜,,其實(shí)簡(jiǎn)單說(shuō)來(lái)Servlet就是一個(gè)Java類,。與一般類的不同之處是,這個(gè)類運(yùn)行在一個(gè)Servlet容器內(nèi),,可以提供session管理和對(duì)象生命周期管理,。因而當(dāng)你使用Servlet的時(shí)候,你可以得到Java平臺(tái)的所有好處,,包括安全性管理,、使用JDBC訪問數(shù)據(jù)庫(kù)以及跨平臺(tái)的能力。而且,,Servlet使用線程,,因而可以開發(fā)出效率更高的Web應(yīng)用。 JavaServer Pages (JSP) JSP技術(shù)是J2EE的一個(gè)關(guān)鍵技術(shù),,它在更高一級(jí)的層次上抽象Servlet,。它可以讓常規(guī)靜態(tài)HTML與動(dòng)態(tài)產(chǎn)生的內(nèi)容相結(jié)合,看起來(lái)像一個(gè)HTML網(wǎng)頁(yè),,卻作為Servlet來(lái)運(yùn)行?,F(xiàn)在有許多商業(yè)應(yīng)用服務(wù)器支持JSP技術(shù),比如BEA WebLogic,、IBM WebSphere,、 JRun等等。使用JSP比用Servlet更簡(jiǎn)單,。如果你有一個(gè)支持JSP的Web服務(wù)器,,并且有一個(gè)JSP文件,,你可以把它放倒任何靜態(tài)HTML文件可以放置的位置,不用編譯,,不用打包,,也不用進(jìn)行ClassPath的設(shè)置,就可以像訪問普通網(wǎng)頁(yè)那樣訪問它,,服務(wù)器會(huì)自動(dòng)幫你做好其他的工作,。 JSP工作原理 JSP 文件看起來(lái)就像一個(gè)普通靜態(tài)HTML文件,只不過(guò)里面包含了一些Java代碼,。它使用.jsp的后綴,,用來(lái)告訴服務(wù)器這個(gè)文件需要特殊的處理。當(dāng)我們?cè)L問一個(gè)JSP頁(yè)面的時(shí)候,,這個(gè)文件首先會(huì)被JSP引擎翻譯為一個(gè)Java源文件,,其實(shí)就是一個(gè)Servlet,并進(jìn)行編譯,,然后像其他Servlet一樣,,由Servlet引擎來(lái)處理。Servlet引擎裝載這個(gè)類,,處理來(lái)自客戶的請(qǐng)求,,并把結(jié)果返回給客戶,如下圖所示: 圖1: 調(diào)用JSP頁(yè)面的流程 以后再有客戶訪問這個(gè)頁(yè)面的時(shí)候,,只要該文件沒有發(fā)生過(guò)更改,,JSP引擎就直接調(diào)用已經(jīng)裝載的Servlet。如果已經(jīng)做過(guò)修改的話,,那就會(huì)再次執(zhí)行以上過(guò)程,,翻譯、編譯并裝載,。其實(shí)這就是所謂的“第一人懲罰”,。因?yàn)槭状卧L問的時(shí)候要執(zhí)行一系列以上的過(guò)程,所以會(huì)耗費(fèi)一些時(shí)間,;以后的訪問就不會(huì)這樣了,。 開發(fā)原則 這一部分我們列出一些開發(fā)原則,重點(diǎn)是JSP頁(yè)面,。關(guān)于如何分離表現(xiàn)和內(nèi)容的MVC因?yàn)橐婕暗?a class="channel_keylink" href="http://www./Article/web/jsp/Index.html">JSP和Servlet的整合,,我們稍候再談。 不要在JSP頁(yè)面中嵌入過(guò)量的Java代碼:對(duì)于非常簡(jiǎn)單或是測(cè)試性的代碼,,把所有的Java 代碼直接放入JSP頁(yè)面內(nèi)是沒有問題的,。但是這種方法不應(yīng)該被過(guò)度使用,否則就會(huì)產(chǎn)生一大堆HTML和Java混合起來(lái)的代碼,讓人難以閱讀和理解,。解決方法是寫一個(gè)單獨(dú)的類,,用來(lái)執(zhí)行相關(guān)的計(jì)算。一旦這個(gè)類測(cè)試通過(guò),,就可以把它放在任何執(zhí)行同樣計(jì)算的場(chǎng)合中,。這樣可以促進(jìn)代碼的復(fù)用。 選擇合適的包含(include)機(jī)制: 如果一個(gè)應(yīng)用中每個(gè)頁(yè)面有一樣的抬頭和底部,,或者還有導(dǎo)航條,,那么就應(yīng)該把它們放到一個(gè)單獨(dú)的文件中,然后在每一個(gè)頁(yè)面中使用包含機(jī)制把它們加入到這個(gè)頁(yè)面中: Include 指令: <%@ include file="filename" %>或等效xml語(yǔ)法 <jsp:directive.includefile=”filename” /> Include 動(dòng)作: <jsp:include page="page.jsp" flush="true" /> Include指令是當(dāng)JSP頁(yè)面翻譯為Servlet的 時(shí)候包含另外一個(gè)文件,,Include 動(dòng)作是當(dāng)請(qǐng)求時(shí)包含另外一個(gè)文件的輸出,。如果被包含的文件不是經(jīng)常改動(dòng)的時(shí)候,我建議使用Include 指令,,這樣速度更快,。如果被包含的文件需要不時(shí)改動(dòng)或者知道請(qǐng)求時(shí)才能決定需要包含的內(nèi)容時(shí),那么應(yīng)該使用Include 動(dòng)作,。 如果你使用JSP標(biāo)準(zhǔn)標(biāo)記庫(kù)(JavaServer pages Standard Tag Library即JSTL)的話,,那么還有第三中包含機(jī)制<c:import>,可以用來(lái)包含本地或者遠(yuǎn)程的資源,。例如: <c:import url="./copyright.html"/> <c:import url="http://www./hello.xml"/> 不要把業(yè)務(wù)邏輯和表示混合在一起: 復(fù)雜的應(yīng)用涉及大量的代碼,,因而把業(yè)務(wù)邏輯和前端的表示相分離就顯得格外重要,這種分離可以讓任何一方的變化不會(huì)影響到另外一方,。所以,所有的JSP代碼都應(yīng)該限制在表示層,,可是如果這樣的話,,你如何實(shí)現(xiàn)你的業(yè)務(wù)邏輯呢?這就是JavaBean所做的事情,。JavaBean技術(shù)是一個(gè)獨(dú)立于平臺(tái)的組件模型,,它讓開發(fā)者編寫、測(cè)試通過(guò)一個(gè)組件后,,可以隨處使用,,提高了復(fù)用性。在JSP技術(shù)中,,JavaBean實(shí)現(xiàn)了業(yè)務(wù)邏輯部分,,它把數(shù)據(jù)返回給JSP頁(yè)面,由JSP頁(yè)面負(fù)責(zé)格式化數(shù)據(jù)并輸出到客戶端的瀏覽器,。在JSP頁(yè)面中使用JavaBean組件的好處是: 產(chǎn)生了可以復(fù)用的組件:任何應(yīng)用都可以使用這些組件 可以把業(yè)務(wù)邏輯和表示相分離:你可以修改數(shù)據(jù)的顯示方式而不用考慮業(yè)務(wù)邏輯,。這樣做的結(jié)果也可以明確工作中開發(fā)人員的分工,網(wǎng)頁(yè)開發(fā)人員可以把精力放到如何顯示數(shù)據(jù)上,Java開發(fā)者則更為關(guān)注業(yè)務(wù)邏輯的實(shí)現(xiàn),。 對(duì)于JavaBean你不用提供源代碼,,這樣你的代碼就不會(huì)被瀏覽器網(wǎng)頁(yè)的人輕易獲得,可以保護(hù)你的勞動(dòng)成果,。 如果你的應(yīng)用中使用了EJB組件,,那么業(yè)務(wù)邏輯就應(yīng)該放置在EJB中,因?yàn)镋JB模型提供了生命周期管理,、事務(wù)管理以及多客戶訪問域?qū)ο螅‥ntity Beans),。你可以仔細(xì)看一下Enterprise BluePrints中的例子,它就是這么做的,。 使用定制的標(biāo)記: 上面我們已經(jīng)討論過(guò),,把所有Java代碼嵌入到JSP頁(yè)面內(nèi)并不合適,因?yàn)榫W(wǎng)頁(yè)開發(fā)人員并不一定懂得Java語(yǔ)言,,更難以理解Java語(yǔ)法,。JavaBean可以封裝很多Java代碼,不過(guò)在JSP頁(yè)面內(nèi)使用JavaBean仍然要求頁(yè)面開發(fā)人員了解一些Java語(yǔ)法,。 JSP技術(shù)中包含了定制標(biāo)記庫(kù)的功能,。Java開發(fā)人員可以生成自己的標(biāo)記庫(kù),這樣網(wǎng)頁(yè)設(shè)計(jì)人員就可以使用類似HTML的語(yǔ)法來(lái)使用這些標(biāo)記,。編寫和使用自己定制的標(biāo)記庫(kù)可以在更大程度上促進(jìn)業(yè)務(wù)邏輯和表示的分離,。使用定制標(biāo)記庫(kù)主要有以下好處: 可以消除在JSP頁(yè)面中使用scriptlet 標(biāo)記使用的任何參數(shù)都可以通過(guò)屬性傳入,從而不需要使用Java代碼就可以達(dá)到希望的目的,。 可以簡(jiǎn)化使用 網(wǎng)頁(yè)設(shè)計(jì)人員不需要學(xué)會(huì)使用Java語(yǔ)法,,他們可以用類似HTML語(yǔ)法就可以使用標(biāo)記。 不懂Java的網(wǎng)頁(yè)設(shè)計(jì)人員可以使用標(biāo)記庫(kù)來(lái)完成單獨(dú)使用HTML不能完成的任務(wù),。 提高了復(fù)用性 標(biāo)記庫(kù)完全可以復(fù)用,,這可以節(jié)省開發(fā)和測(cè)試的時(shí)間。Scriptlet代碼只能在“拷貝粘貼”級(jí)別上進(jìn)行“復(fù)用”,。 簡(jiǎn)單說(shuō)來(lái),,你可以像用HTML構(gòu)建表示層一樣使用標(biāo)記庫(kù)完成非常復(fù)雜的任務(wù)。下面是表頁(yè)標(biāo)記庫(kù)的一些注意事項(xiàng): 1. 保持簡(jiǎn)潔性:如果一個(gè)標(biāo)記需要好幾個(gè)屬性的話,,那么盡可能把它分為幾個(gè)標(biāo)記,。 2. 保持復(fù)用性:同標(biāo)記的使用人員(網(wǎng)頁(yè)設(shè)計(jì)人員)多多交流,盡量開發(fā)出可以高度復(fù)用的標(biāo)記庫(kù),。 3. 不要一切都從頭開始:現(xiàn)在已經(jīng)有一些可以免費(fèi)使用的標(biāo)記庫(kù),,比如Jakarta Taglibs。如果你要用到一個(gè)標(biāo)記,,先看看是不是已經(jīng)有現(xiàn)成的可以使用,。 不要“重新發(fā)明輪子”,,不要一切從頭開始: 通過(guò)定制組件可以提高復(fù)用性,不過(guò)定制組件仍然需要編寫,、測(cè)試和調(diào)試程序,。問題是這個(gè)事情別人可能已經(jīng)實(shí)現(xiàn)了,而且你的實(shí)現(xiàn)方式并不一定比人家做得更好,。這就是JSP標(biāo)準(zhǔn)標(biāo)記庫(kù)(JavaServer Pages Standard Tag Library, JSTL)要做的事情(JSTL請(qǐng)參考JSTL官方網(wǎng)站),。JSTL提供了循環(huán)、讀屬性,、遍歷各種數(shù)據(jù)結(jié)構(gòu),、條件表達(dá)式求值等各種標(biāo)記。它也提供了一些復(fù)雜的標(biāo)記,,甚至像解析XML文檔的標(biāo)記它都有,。所以如果你要用到一個(gè)標(biāo)記的話,最好先看看有沒有別人已經(jīng)實(shí)現(xiàn)的可以使用,,而不要次次從頭開始,,自己搞一套。 使用JSTL表達(dá)使語(yǔ)言(JSTL Expression Language): 傳遞給JSP頁(yè)面的數(shù)據(jù)一般通過(guò)JSP作用域屬性或者請(qǐng)求參數(shù)來(lái)進(jìn)行,。專門為網(wǎng)頁(yè)開發(fā)者設(shè)計(jì)的表達(dá)式語(yǔ)言(Expression Language, EL)把使用作用域屬性傳遞信息作為從業(yè)務(wù)邏輯向JSP頁(yè)面?zhèn)鬟f信息的標(biāo)準(zhǔn)方式,。這里要注意的是,EL只是JSP技術(shù)中關(guān)鍵的一個(gè)方面,,并不是一種通用的程序設(shè)計(jì)語(yǔ)言,。相反,它只是一種數(shù)據(jù)訪問語(yǔ)言,,它可以簡(jiǎn)化應(yīng)用程序的數(shù)據(jù)的訪問,,不用Scriptlet和請(qǐng)求時(shí)表達(dá)式求值就可以訪問數(shù)據(jù)。 在JSP中,,網(wǎng)頁(yè)設(shè)計(jì)師要使用表達(dá)式語(yǔ)法<%= name %>或JavaBean組件來(lái)取得某些變量或屬性的值,,例如: <tagLib:tag attribute="<%= pageContext.getAttribute("name") %>"> 或 <%= aCustomerBean.getAddress().getCountry() %> 表達(dá)使語(yǔ)言讓網(wǎng)頁(yè)設(shè)計(jì)師可以使用簡(jiǎn)化的語(yǔ)法來(lái)訪問信息。如果你只是要訪問一個(gè)簡(jiǎn)單的變量,,你可以使用這樣的語(yǔ)法: <tagLib:tag attribute="${name}"> 如果你要訪問一個(gè)嵌套JavaBean的屬性,你可以這樣: <tagLib:tag attribute ="${ aCustomerBean.address.country}"> 表達(dá)式語(yǔ)言(EL)借用了JavaScript 的語(yǔ)法,,所以如果你對(duì)JavaScript 很熟悉的話,,你就會(huì)覺得巨爽。 使用過(guò)濾器(filter): 過(guò)濾器是一個(gè)對(duì)象,,可以傳輸請(qǐng)求或修改響應(yīng),。它可以在請(qǐng)求到達(dá)Servlet/JSP之前對(duì)其進(jìn)行預(yù)處理,而且能夠在響應(yīng)離開Servlet/JSP之后對(duì)其進(jìn)行后處理,。所以如果你有幾個(gè)Servlet/JSP需要執(zhí)行同樣的數(shù)據(jù)轉(zhuǎn)換或頁(yè)面處理的話,,你就可以寫一個(gè)過(guò)濾器類,然后在部署描述文件(web.xml)中把該過(guò)濾器與對(duì)應(yīng)的Servlet/JSP聯(lián)系起來(lái)。 創(chuàng)建過(guò)濾器其實(shí)很容易,,你只須實(shí)現(xiàn)javax.servlet.Filter接口及它的三個(gè)方法: public void init(FilterConfig config) public void doFilter(ServletRequest req, ServletResponse rep, FilterChain chain) public void destroy() 這樣,,你就可以完成你的過(guò)濾器。 使用可移植的安全模型: 大部分的應(yīng)用服務(wù)器都提供了安全模型,,不過(guò)一般它們都是針對(duì)某一個(gè)服務(wù)器或某一個(gè)廠商專有的,。如果你的應(yīng)用需要移植的話,那么你的應(yīng)用最好使用可以移植的 安全模型,。如果你的應(yīng)用有一些預(yù)先定義的固定用戶的話,,那么你可以使用FROM驗(yàn)證和BASIC驗(yàn)證??墒侨绻阋?jiǎng)討B(tài)生成客戶的話(一般都是這種情 況),,你可能就需要使用服務(wù)器特定的API來(lái)創(chuàng)建和管理用戶。這樣當(dāng)你的應(yīng)用移植到另外一個(gè)服務(wù)器時(shí),,你可能就會(huì)碰到API不兼容的問題,。這種情況下,最 好的解決方法是使用適配器(Adapter)模式(如果你對(duì)設(shè)計(jì)模式不熟悉的話,,請(qǐng)參看GoF的《設(shè)計(jì)模式》一書),。 用數(shù)據(jù)庫(kù)來(lái)保存持久性數(shù)據(jù): Servlet/JSP中可以使用HttpSession對(duì)象也就是會(huì)話對(duì)象來(lái)保存用戶的臨時(shí)數(shù)據(jù)。不過(guò)如果你想保存持久性數(shù)據(jù)的時(shí)候,,你應(yīng)該使用數(shù)據(jù)庫(kù),,數(shù)據(jù)保存數(shù)據(jù)會(huì)更安全,而且對(duì)客戶所用的瀏覽器沒有什么要求,。這樣即使你的應(yīng)用服務(wù)器由于某種原因崩潰了,,你的數(shù)據(jù)依然良好。 高速緩存頁(yè)面: 應(yīng)用程序中總有一些東西是相對(duì)固定的,,而另外一些東西是經(jīng)常變化的,。你應(yīng)該使用靜態(tài)的HTML文檔來(lái)存儲(chǔ)那些相對(duì)固定的內(nèi)容,這樣客戶端就可以進(jìn)行高速緩存,,客戶每次訪問你的應(yīng)用時(shí),,只需訪問已經(jīng)改動(dòng)的部分。這樣可以加快客戶的訪問速度,。 使用連接池: 如果你要自己寫數(shù)據(jù)庫(kù)訪問代碼的話,,我覺得使用你應(yīng)該學(xué)會(huì)如何使用數(shù)據(jù)庫(kù)連接池技術(shù)。每一個(gè)服務(wù)器都有針對(duì)數(shù)據(jù)庫(kù)連接池的配置文檔,,你要學(xué)習(xí)一下如何使用,。數(shù)據(jù)庫(kù)連接池可以加速你的應(yīng)用的數(shù)據(jù)訪問的速度,而且由于服務(wù)器替你管理了數(shù)據(jù)庫(kù)連接,,這可以節(jié)省你的很多工作,。 緩存數(shù)據(jù)庫(kù)的訪問結(jié)果: 如果你的應(yīng)用要對(duì)數(shù)據(jù)庫(kù)進(jìn)行頻繁訪問的話,,你可以使用一個(gè)對(duì)象來(lái)緩存你的數(shù)據(jù),這樣你就可以節(jié)省大量訪問數(shù)據(jù)庫(kù)的開銷,。在《J2EE核心模式》和《實(shí)用J2EE設(shè)計(jì)模式編程指南》兩本書中都有關(guān)于值對(duì)象模式(Value Object Pattern)的詳細(xì)探討,,你可以參考這兩本書來(lái)獲得相應(yīng)的知識(shí)。 使用數(shù)據(jù)訪問對(duì)象模式:如果你的應(yīng)用需要訪問多個(gè)數(shù)據(jù)庫(kù)系 統(tǒng)或者可能會(huì)移植到其它的存儲(chǔ)系統(tǒng)中,,那么你針對(duì)特定廠商的優(yōu)化代碼就可能會(huì)失效,。使用通用的代碼存在執(zhí)行效率的問題,而使用優(yōu)化代碼又存在移植的問題,。 所以就產(chǎn)生了數(shù)據(jù)訪問對(duì)象模式(Data Access Object Pattern, DAO),,該模式既提供了各數(shù)據(jù)庫(kù)廠商的適應(yīng)性,又能利用到他們提供的獨(dú)特的好處,。按照面向?qū)ο?/a>的分離任務(wù)的原則,,該模式將與企業(yè)信息系統(tǒng)(Enterprise Information System, EIS)通訊需要的邏輯隔離到它自己的類中。這樣,,事物對(duì)象,,如Servlet/JSP組件、JavaBean就可以利用數(shù)據(jù)訪問對(duì)象(DAO)處理所有與EIS有關(guān)的事務(wù),。 最好采用JSP的XML語(yǔ)法: JSP技術(shù)中經(jīng)常存在著兩種完成同一個(gè)任務(wù)的語(yǔ)法,,一種是常規(guī)的JSP語(yǔ)法,一種是對(duì)應(yīng)的XML語(yǔ)法,。雖然兩種語(yǔ)法作用相同,,你最好還是使用XML語(yǔ)法。存在兩種語(yǔ)法的原因是,,JSP語(yǔ)法可以與以前的代碼兼容,,而J2EE使用XML作為其交換數(shù)據(jù)的核心,所以同時(shí)提供了XML語(yǔ)法,。隨著J2EE的發(fā)展,,XML的作用會(huì)越來(lái)越大,所以我建議你使用XML語(yǔ)法,。 研究Sun提供的J2EE BluePrints: Sun的Enterprise BluePrints 提供了大量指導(dǎo)原則,、設(shè)計(jì)模式和很好的例子(寵物店,Pet Store),。你可以好好研究一下這些內(nèi)容,,這樣可以提高你的設(shè)計(jì)和開發(fā)水平。 整合Servlet和JSP JSP技術(shù)規(guī)范種給出了兩種使用JSP開發(fā)Web應(yīng)用的方式,,這兩種方式可以歸納為模型一和模型二,這兩種模型的主要差別在于它們處理業(yè)務(wù)的流程不同,。模型一,,如下圖所示,,稱之為JSP+JavaBeans模型。在這一模型中,,JSP頁(yè)面獨(dú)自響應(yīng)請(qǐng)求并將處理結(jié)果返回給客戶,,所有的數(shù)據(jù)通過(guò)JavaBean來(lái)處理,JSP實(shí)現(xiàn)頁(yè)面的表現(xiàn),。 圖2: JSP模型一 從上圖可以看出,,模型一也實(shí)現(xiàn)了頁(yè)面表現(xiàn)和業(yè)務(wù)邏輯相分離。然而使用這種方式就要在JSP頁(yè)面使用大量的Java代 碼,,當(dāng)需要處理的業(yè)務(wù)邏輯很復(fù)雜時(shí),,這種情況會(huì)變得非常糟糕。大量嵌入式代碼使整個(gè)頁(yè)面程序變得異常復(fù)雜,。對(duì)于前端界面設(shè)計(jì)的網(wǎng)頁(yè)開發(fā)人員來(lái)說(shuō),,這簡(jiǎn)直是 一場(chǎng)噩夢(mèng)。所以,,模型一不能滿足大型應(yīng)用的需要,,但是對(duì)于小型應(yīng)用,因?yàn)樵撃P秃?jiǎn)單,,不用涉及諸多要素,,從而可以很好地滿足小型應(yīng)用的需要,所以在簡(jiǎn)單應(yīng) 用中,,可以考慮模型一,。 模型二,如下圖所示,,稱之為JSP+Servlet+JavaBeans模型,。這一模型結(jié)合了JSP和Servlet技術(shù),充分利用了JSP和Servlet兩種技術(shù)原有的優(yōu)勢(shì),。這個(gè)模型使用JSP技術(shù)來(lái)表現(xiàn)頁(yè)面,,使用Servlet技術(shù)完成大量的事務(wù)處理,使用Bean來(lái)存儲(chǔ)數(shù)據(jù),。Servlet用來(lái)處理請(qǐng)求的事務(wù),,充當(dāng)一個(gè)控制者的角色,并負(fù)責(zé)向客戶發(fā)送請(qǐng)求,。它創(chuàng)建JSP需要的Bean和對(duì)象,,然后根據(jù)用戶請(qǐng)求的行為,決定將哪個(gè)JSP頁(yè)面發(fā)送給客戶,。 圖3: JSP模型二 從開發(fā)的觀點(diǎn)看,,模型二具有更清晰的頁(yè)面表現(xiàn),清楚的開發(fā)角色的劃分,,可以充分利用開發(fā)團(tuán)隊(duì)中的網(wǎng)頁(yè)設(shè)計(jì)人員和Java開發(fā)人員,。這些優(yōu)勢(shì)在大型項(xiàng)目中表現(xiàn)得尤為突出,,網(wǎng)頁(yè)設(shè)計(jì)人員可以充分發(fā)揮自己的美術(shù)和設(shè)計(jì)才能來(lái)充分表現(xiàn)頁(yè)面,程序編寫人員可以充分發(fā)揮自己的業(yè)務(wù)邏輯處理思維,,實(shí)現(xiàn)項(xiàng)目中的業(yè)務(wù)處理,。 另外,從設(shè)計(jì)結(jié)構(gòu)來(lái)看,,這種模型充分體現(xiàn)了模型視圖控制器(MVC)的設(shè)計(jì)架構(gòu),。事實(shí)上,現(xiàn)存的很多開發(fā)框架都是基于這種模型的,,充分實(shí)現(xiàn)了MVC ,,例如Apache Struts框架和JavaServer Faces框架 |
|