Java Tools

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            83 隨筆 :: 0 文章 :: 16 評論 :: 0 Trackbacks
          ServletJSP技術是用Java開發服務器端應用的主要技術,是開發商務應用表示端的標準。Java開發者喜歡使用它有多種原因,其一是對于已經熟悉Java語言的開發者來說這個技術容易學習;其二是Java把“一次編寫,到處運行”的理念帶入到Web應用中,實現了“一次編寫,到處實現”。而且更為重要的是,如果遵循一些良好的設計原則的話,就可以把表示和內容相分離,創造出高質量的、可以復用的、易于維護和修改的應用程序。比方說,在HTML文檔中如果嵌入過多的Java代碼(scriptlet),就會導致開發出來的應用非常復雜、難以閱讀、不容易復用,而且對以后的維護和修改也會造成困難。事實上,在CSDN的JSP/Servlet論壇中,經常可以看到一些提問,代碼很長,可以邏輯卻不是很清晰,大量的HTML和Java代碼混雜在一起,讓人看得一頭霧水。這就是隨意開發的弊端。

            如果你已經基本了解JSPServlet的各項技術(最好也開發過一些Web應用),那么我們可以一起探討一下如何開發“好”的應用的一些指導原則。我們首先對ServletJSP技術做一個瀏覽。

            ServletJSP概覽

            早期的動態網頁主要采用CGI(Common Gateway Interface,公共網關接口)技術,你可以使用不同的語言編寫CGI程序,如VB、C/C++Delphi等。雖然CGI技術發展成熟且功能強大,但由于編程困難、效率低下、修改復雜等缺點,所以有逐漸被取代的趨勢。在所有的新技術中,JSP/Servlet具備更高效、更容易編程、功能更強、更安全和具有良好的可移植性,因而被許多人認為是未來最有發展前途的動態網站技術。

            與CGI相似,Servlet支持請求/響應模型。當一個客戶向服務器遞交一個請求時,服務器把請求送給ServletServlet負責處理請求并生成響應,然后送給服務器,再由服務器發送給客戶。與CGI不同的是,Servlet沒有生成新的進程,而是與HTTP Server處于同一進程中。它通過使用線程技術,減小了服務器的開銷。Servlet處理請求的過程是這樣的:當收到來自客戶端的請求后,調用service方法,該方法中Servlet先判斷到來的請求是什么類型的(GET/POST/HEAD…),然后調用相應的處理方法(doGet/doPost/doHead…)并生成響應。

            別看這么復雜,其實簡單說來Servlet就是一個Java類。與一般類的不同之處是,這個類運行在一個Servlet容器內,可以提供session管理和對象生命周期管理。因而當你使用Servlet的時候,你可以得到Java平臺的所有好處,包括安全性管理、使用JDBC訪問數據庫以及跨平臺的能力。而且,Servlet使用線程,因而可以開發出效率更高的Web應用。

            JavaServer Pages (JSP)

            JSP技術是J2EE的一個關鍵技術,它在更高一級的層次上抽象Servlet。它可以讓常規靜態HTML與動態產生的內容相結合,看起來像一個HTML網頁,卻作為Servlet來運行。現在有許多商業應用服務器支持JSP技術,比如BEA WebLogic、IBM WebSphere、 JRun等等。使用JSP比用Servlet更簡單。如果你有一個支持JSP的Web服務器,并且有一個JSP文件,你可以把它放倒任何靜態HTML文件可以放置的位置,不用編譯,不用打包,也不用進行ClassPath的設置,就可以像訪問普通網頁那樣訪問它,服務器會自動幫你做好其他的工作。

            JSP工作原理

            JSP 文件看起來就像一個普通靜態HTML文件,只不過里面包含了一些Java代碼。它使用.jsp的后綴,用來告訴服務器這個文件需要特殊的處理。當我們訪問一個JSP頁面的時候,這個文件首先會被JSP引擎翻譯為一個Java源文件,其實就是一個Servlet,并進行編譯,然后像其他Servlet一樣,由Servlet引擎來處理。Servlet引擎裝載這個類,處理來自客戶的請求,并把結果返回給客戶,如下圖所示:


          圖1: 調用JSP頁面的流程

            以后再有客戶訪問這個頁面的時候,只要該文件沒有發生過更改,JSP引擎就直接調用已經裝載的Servlet。如果已經做過修改的話,那就會再次執行以上過程,翻譯、編譯并裝載。其實這就是所謂的“第一人懲罰”。因為首次訪問的時候要執行一系列以上的過程,所以會耗費一些時間;以后的訪問就不會這樣了。

          開發原則


            這一部分我們列出一些開發原則,重點是JSP頁面。關于如何分離表現和內容的MVC因為要涉及到JSPServlet的整合,我們稍候再談。

            不要在JSP頁面中嵌入過量的Java代碼:對于非常簡單或是測試性的代碼,把所有的Java 代碼直接放入JSP頁面內是沒有問題的。但是這種方法不應該被過度使用,否則就會產生一大堆HTML和Java混合起來的代碼,讓人難以閱讀和理解。解決方法是寫一個單獨的類,用來執行相關的計算。一旦這個類測試通過,就可以把它放在任何執行同樣計算的場合中。這樣可以促進代碼的復用。

            選擇合適的包含(include)機制: 如果一個應用中每個頁面有一樣的抬頭和底部,或者還有導航條,那么就應該把它們放到一個單獨的文件中,然后在每一個頁面中使用包含機制把它們加入到這個頁面中:

          Include 指令: <%@ include file="filename" %>或等效xml語法
          <jsp:directive.includefile=”filename” />

          Include 動作: <jsp:include page="page.jsp" flush="true" />

            Include指令是當JSP頁面翻譯為Servlet的時候包含另外一個文件,Include 動作是當請求時包含另外一個文件的輸出。如果被包含的文件不是經常改動的時候,我建議使用Include 指令,這樣速度更快。如果被包含的文件需要不時改動或者知道請求時才能決定需要包含的內容時,那么應該使用Include 動作。

            如果你使用JSP標準標記庫(JavaServer pages Standard Tag Library即JSTL)的話,那么還有第三中包含機制<c:import>,可以用來包含本地或者遠程的資源。例如:

          <c:import url="./copyright.html"/>
          <c:import url="http://www.somewhere.com/hello.xml"/>

            不要把業務邏輯和表示混合在一起: 復雜的應用涉及大量的代碼,因而把業務邏輯和前端的表示相分離就顯得格外重要,這種分離可以讓任何一方的變化不會影響到另外一方。所以,所有的JSP代碼都應該限制在表示層,可是如果這樣的話,你如何實現你的業務邏輯呢?這就是JavaBean所做的事情。JavaBean技術是一個獨立于平臺的組件模型,它讓開發者編寫、測試通過一個組件后,可以隨處使用,提高了復用性。在JSP技術中,JavaBean實現了業務邏輯部分,它把數據返回給JSP頁面,由JSP頁面負責格式化數據并輸出到客戶端的瀏覽器。在JSP頁面中使用JavaBean組件的好處是:

            產生了可以復用的組件:任何應用都可以使用這些組件

            可以把業務邏輯和表示相分離:你可以修改數據的顯示方式而不用考慮業務邏輯。這樣做的結果也可以明確工作中開發人員的分工,網頁開發人員可以把精力放到如何顯示數據上,Java開發者則更為關注業務邏輯的實現。

            對于JavaBean你不用提供源代碼,這樣你的代碼就不會被瀏覽器網頁的人輕易獲得,可以保護你的勞動成果。

            如果你的應用中使用了EJB組件,那么業務邏輯就應該放置在EJB中,因為EJB模型提供了生命周期管理、事務管理以及多客戶訪問域對象(Entity Beans)。你可以仔細看一下Enterprise BluePrints中的例子,它就是這么做的。

            使用定制的標記: 上面我們已經討論過,把所有Java代碼嵌入到JSP頁面內并不合適,因為網頁開發人員并不一定懂得Java語言,更難以理解Java語法。JavaBean可以封裝很多Java代碼,不過在JSP頁面內使用JavaBean仍然要求頁面開發人員了解一些Java語法。

            JSP技術中包含了定制標記庫的功能。Java開發人員可以生成自己的標記庫,這樣網頁設計人員就可以使用類似HTML的語法來使用這些標記。編寫和使用自己定制的標記庫可以在更大程度上促進業務邏輯和表示的分離。使用定制標記庫主要有以下好處:

            可以消除在JSP頁面中使用scriptlet 標記使用的任何參數都可以通過屬性傳入,從而不需要使用Java代碼就可以達到希望的目的。

            可以簡化使用 網頁設計人員不需要學會使用Java語法,他們可以用類似HTML語法就可以使用標記。
          不懂Java的網頁設計人員可以使用標記庫來完成單獨使用HTML不能完成的任務。

            提高了復用性 標記庫完全可以復用,這可以節省開發和測試的時間。Scriptlet代碼只能在“拷貝粘貼”級別上進行“復用”。

            簡單說來,你可以像用HTML構建表示層一樣使用標記庫完成非常復雜的任務。下面是表頁標記庫的一些注意事項:

            1. 保持簡潔性:如果一個標記需要好幾個屬性的話,那么盡可能把它分為幾個標記。

            2. 保持復用性:同標記的使用人員(網頁設計人員)多多交流,盡量開發出可以高度復用的標記庫。

            3. 不要一切都從頭開始:現在已經有一些可以免費使用的標記庫,比如Jakarta Taglibs。如果你要用到一個標記,先看看是不是已經有現成的可以使用。

            不要“重新發明輪子”,不要一切從頭開始: 通過定制組件可以提高復用性,不過定制組件仍然需要編寫、測試和調試程序。問題是這個事情別人可能已經實現了,而且你的實現方式并不一定比人家做得更好。這就是JSP標準標記庫(JavaServer Pages Standard Tag Library, JSTL)要做的事情(JSTL請參考JSTL官方網站)。JSTL提供了循環、讀屬性、遍歷各種數據結構、條件表達式求值等各種標記。它也提供了一些復雜的標記,甚至像解析XML文檔的標記它都有。所以如果你要用到一個標記的話,最好先看看有沒有別人已經實現的可以使用,而不要次次從頭開始,自己搞一套。

            使用JSTL表達使語言(JSTL Expression Language): 傳遞給JSP頁面的數據一般通過JSP作用域屬性或者請求參數來進行。專門為網頁開發者設計的表達式語言(Expression Language, EL)把使用作用域屬性傳遞信息作為從業務邏輯向JSP頁面傳遞信息的標準方式。這里要注意的是,EL只是JSP技術中關鍵的一個方面,并不是一種通用的程序設計語言。相反,它只是一種數據訪問語言,它可以簡化應用程序的數據的訪問,不用Scriptlet和請求時表達式求值就可以訪問數據。

            在JSP中,網頁設計師要使用表達式語法<%= name %>或JavaBean組件來取得某些變量或屬性的值,例如:

          <tagLib:tag attribute="<%=

          pageContext.getAttribute("name") %>">

            或

          <%= aCustomerBean.getAddress().getCountry() %>

            表達使語言讓網頁設計師可以使用簡化的語法來訪問信息。如果你只是要訪問一個簡單的變量,你可以使用這樣的語法:

          <tagLib:tag attribute="${name}">

            如果你要訪問一個嵌套JavaBean的屬性,你可以這樣:

          <tagLib:tag attribute ="${

          aCustomerBean.address.country}">

            表達式語言(EL)借用了JavaScript 的語法,所以如果你對JavaScript 很熟悉的話,你就會覺得巨爽。

            使用過濾器(filter): 過濾器是一個對象,可以傳輸請求或修改響應。它可以在請求到達Servlet/JSP之前對其進行預處理,而且能夠在響應離開Servlet/JSP之后對其進行后處理。所以如果你有幾個Servlet/JSP需要執行同樣的數據轉換或頁面處理的話,你就可以寫一個過濾器類,然后在部署描述文件(web.xml)中把該過濾器與對應的Servlet/JSP聯系起來。

            創建過濾器其實很容易,你只須實現javax.servlet.Filter接口及它的三個方法:

          public void init(FilterConfig config)

          public void doFilter(ServletRequest req, ServletResponse rep,

          FilterChain chain)

          public void destroy()

            這樣,你就可以完成你的過濾器。

          使用可移植的安全模型:大部分的應用服務器都提供了安全模型,不過一般它們都是針對某一個服務器或某一個廠商專有的。如果你的應用需要移植的話,那么你的應用最好使用可以移植的安全模型。如果你的應用有一些預先定義的固定用戶的話,那么你可以使用FROM驗證和BASIC驗證。可是如果你要動態生成客戶的話(一般都是這種情況),你可能就需要使用服務器特定的API來創建和管理用戶。這樣當你的應用移植到另外一個服務器時,你可能就會碰到API不兼容的問題。這種情況下,最好的解決方法是使用適配器(Adapter)模式(如果你對設計模式不熟悉的話,請參看GoF的《設計模式》一書)。

            用數據庫來保存持久性數據: Servlet/JSP中可以使用HttpSession對象也就是會話對象來保存用戶的臨時數據。不過如果你想保存持久性數據的時候,你應該使用數據庫,數據保存數據會更安全,而且對客戶所用的瀏覽器沒有什么要求。這樣即使你的應用服務器由于某種原因崩潰了,你的數據依然良好。

            高速緩存頁面: 應用程序中總有一些東西是相對固定的,而另外一些東西是經常變化的。你應該使用靜態的HTML文檔來存儲那些相對固定的內容,這樣客戶端就可以進行高速緩存,客戶每次訪問你的應用時,只需訪問已經改動的部分。這樣可以加快客戶的訪問速度。

            使用連接池: 如果你要自己寫數據庫訪問代碼的話,我覺得使用你應該學會如何使用數據庫連接池技術。每一個服務器都有針對數據庫連接池的配置文檔,你要學習一下如何使用。數據庫連接池可以加速你的應用的數據訪問的速度,而且由于服務器替你管理了數據庫連接,這可以節省你的很多工作。

            緩存數據庫的訪問結果: 如果你的應用要對數據庫進行頻繁訪問的話,你可以使用一個對象來緩存你的數據,這樣你就可以節省大量訪問數據庫的開銷。在《J2EE核心模式》和《實用J2EE設計模式編程指南》兩本書中都有關于值對象模式(Value Object Pattern)的詳細探討,你可以參考這兩本書來獲得相應的知識。

            使用數據訪問對象模式:如果你的應用需要訪問多個數據庫系統或者可能會移植到其它的存儲系統中,那么你針對特定廠商的優化代碼就可能會失效。使用通用的代碼存在執行效率的問題,而使用優化代碼又存在移植的問題。所以就產生了數據訪問對象模式(Data Access Object Pattern, DAO),該模式既提供了各數據庫廠商的適應性,又能利用到他們提供的獨特的好處。按照面向對象的分離任務的原則,該模式將與企業信息系統(Enterprise Information System, EIS)通訊需要的邏輯隔離到它自己的類中。這樣,事物對象,如Servlet/JSP組件、JavaBean就可以利用數據訪問對象(DAO)處理所有與EIS有關的事務。

            最好采用JSPXML語法: JSP技術中經常存在著兩種完成同一個任務的語法,一種是常規的JSP語法,一種是對應的XML語法。雖然兩種語法作用相同,你最好還是使用XML語法。存在兩種語法的原因是,JSP語法可以與以前的代碼兼容,而J2EE使用XML作為其交換數據的核心,所以同時提供了XML語法。隨著J2EE的發展,XML的作用會越來越大,所以我建議你使用XML語法。

            研究Sun提供的J2EE BluePrints: Sun的Enterprise BluePrints 提供了大量指導原則、設計模式和很好的例子(寵物店,Pet Store)。你可以好好研究一下這些內容,這樣可以提高你的設計和開發水平。

            整合ServletJSP

            JSP技術規范種給出了兩種使用JSP開發Web應用的方式,這兩種方式可以歸納為模型一和模型二,這兩種模型的主要差別在于它們處理業務的流程不同。模型一,如下圖所示,稱之為JSP+JavaBeans模型。在這一模型中,JSP頁面獨自響應請求并將處理結果返回給客戶,所有的數據通過JavaBean來處理,JSP實現頁面的表現。


          圖2: JSP模型一

            從上圖可以看出,模型一也實現了頁面表現和業務邏輯相分離。然而使用這種方式就要在JSP頁面使用大量的Java代碼,當需要處理的業務邏輯很復雜時,這種情況會變得非常糟糕。大量嵌入式代碼使整個頁面程序變得異常復雜。對于前端界面設計的網頁開發人員來說,這簡直是一場噩夢。所以,模型一不能滿足大型應用的需要,但是對于小型應用,因為該模型簡單,不用涉及諸多要素,從而可以很好地滿足小型應用的需要,所以在簡單應用中,可以考慮模型一。

            模型二,如下圖所示,稱之為JSP+Servlet+JavaBeans模型。這一模型結合了JSPServlet技術,充分利用了JSPServlet兩種技術原有的優勢。這個模型使用JSP技術來表現頁面,使用Servlet技術完成大量的事務處理,使用Bean來存儲數據。Servlet用來處理請求的事務,充當一個控制者的角色,并負責向客戶發送請求。它創建JSP需要的Bean和對象,然后根據用戶請求的行為,決定將哪個JSP頁面發送給客戶。


          圖3: JSP模型二

            從開發的觀點看,模型二具有更清晰的頁面表現,清楚的開發角色的劃分,可以充分利用開發團隊中的網頁設計人員和Java開發人員。這些優勢在大型項目中表現得尤為突出,網頁設計人員可以充分發揮自己的美術和設計才能來充分表現頁面,程序編寫人員可以充分發揮自己的業務邏輯處理思維,實現項目中的業務處理。

            另外,從設計結構來看,這種模型充分體現了模型視圖控制器(MVC)的設計架構。事實上,現存的很多開發框架都是基于這種模型的,充分實現了MVC ,例如Apache Struts框架和JavaServer Faces框架
          posted on 2007-07-02 12:51 和田雨 閱讀(286) 評論(0)  編輯  收藏 所屬分類: JSPServlet
          主站蜘蛛池模板: 佛山市| 霸州市| 新和县| 张北县| 颍上县| 梧州市| 谢通门县| 宁河县| 咸丰县| 长治县| 新泰市| 龙里县| 囊谦县| 扎兰屯市| 通许县| 民乐县| 香河县| 富蕴县| 奎屯市| 中卫市| 襄垣县| 蒙自县| 潮州市| 长岭县| 怀仁县| 灵武市| 民权县| 娱乐| 永兴县| 余干县| 斗六市| 高密市| 西贡区| 随州市| 祁门县| 五华县| 井研县| 兴海县| 长宁区| 湖口县| 北海市|