svg_007

           

          2005年11月8日

          web應(yīng)用(轉(zhuǎn)自Sun社區(qū))

          Web應(yīng)用是Web服務(wù)的一種動(dòng)態(tài)擴(kuò)展。Web應(yīng)用可分為兩類(lèi):
          • ?面向表示的Web應(yīng)用。在響應(yīng)請(qǐng)求時(shí),面向表示的Web應(yīng)用產(chǎn)生動(dòng)態(tài)的Web頁(yè)面,這種頁(yè)面包含了各種不同的標(biāo)記語(yǔ)言(如HTML, XML, 等等)。
          • 面向服務(wù)的Web應(yīng)用。面向服務(wù)的Web應(yīng)用實(shí)現(xiàn)細(xì)粒度Web服務(wù)的端點(diǎn)。面向服務(wù)Web應(yīng)用通常為面向表示應(yīng)用所調(diào)用。

          在Java2平臺(tái)上,Web組件為Web 服務(wù)器提供了動(dòng)態(tài)擴(kuò)展能力。Web組件可以是Java Servlets或者JSP頁(yè)面。Servlets是Java編程語(yǔ)言中用于動(dòng)態(tài)地處理請(qǐng)求和建立響應(yīng)的一種類(lèi)。JSP頁(yè)面是基于文本的文檔,它像 servlets一樣執(zhí)行,但是允許使用更自然的方法來(lái)創(chuàng)建靜態(tài)內(nèi)容。盡管servlet和JSP頁(yè)面可以交替地使用,但是它們各有千秋。 Servlets最適合于面向服務(wù)的Web應(yīng)用,同時(shí)還擅長(zhǎng)于管理面向表示的Web服務(wù)的控制功能,例如發(fā)送請(qǐng)求和處理非原文的數(shù)據(jù)。而JSP頁(yè)面則更適 合于產(chǎn)生基于文本的標(biāo)記,例如:HTML、SVG、WML以及XML等。

          Web組件以一個(gè)名為Web容器 的運(yùn)行時(shí)平臺(tái)中的服務(wù)作為支撐。在Java Web服務(wù)開(kāi)發(fā)包(Java Web Services Developer Pack, Java WSDP)中的Web組件在Tomcat Web容器內(nèi)運(yùn)行。Web容器提供了一些服務(wù),例如請(qǐng)求發(fā)送、安全、并發(fā)以及生命周期管理。它還使得Web組件可以訪問(wèn)多種API, 例如命名、事務(wù)處理以及e-mail等方面的API。

          本章里描述了Web應(yīng)用的組織、配置以及安裝和部署過(guò)程。第11章和第12章中講述如何開(kāi)發(fā)面向服務(wù)的Web應(yīng)用的Web組件。第14章和第15章講述如何開(kāi)發(fā)面向表示W(wǎng)eb的應(yīng)用的Web組件。JSP技術(shù)的許多特征是由Java Servlet技術(shù)決定的,因此即使你不打算編寫(xiě)servlet,也應(yīng)該熟悉這方面的知識(shí)。

          大多數(shù)Web應(yīng)用都使用HTTP協(xié)議,而且對(duì)HTTP的支持也正是Web組件的一個(gè)主要方面。對(duì)于HTTP協(xié)議特征的簡(jiǎn)要總結(jié),參見(jiàn)HTTP概述

          Web應(yīng)用的生命周期

          Web應(yīng)用由Web組件、靜態(tài)資源文件(如圖像)、幫助類(lèi)和庫(kù)組成。Java WSDP提供許多支持服務(wù),用于增強(qiáng)Web組件的性能并使得它們更易于開(kāi)發(fā)。不過(guò),由于要充分考慮這些支持服務(wù),所以Web應(yīng)用在創(chuàng)建和運(yùn)行過(guò)程上與傳統(tǒng)的stand-alone式的Java類(lèi)有所不同。

          在Web應(yīng)用被部署以后,就可以對(duì)其行為的某些方面進(jìn)行配置。配置信息通過(guò)Web應(yīng)用部署描述文件來(lái)維護(hù),該文件是一種XML格式的文本文件。部署描述文件必須遵從Java Servlet規(guī)范中描述的模式。

          創(chuàng)建、部署和執(zhí)行Web應(yīng)用的過(guò)程可以總結(jié)為以下幾步:

          1.開(kāi)發(fā)Web組件代碼(可能還包括部署描述文件)。

          2.建立Web應(yīng)用組件連同所有靜態(tài)資源(例如圖像)和組件要引用到的幫助類(lèi)。

          3.將應(yīng)用安裝或部署到Web容器中。

          4.訪問(wèn)指向該Web應(yīng)用的URL。

          開(kāi) 發(fā)Web組件代碼這方面的知識(shí)將在以后的章節(jié)中講述。接下來(lái)的幾節(jié)將對(duì)步驟2到步驟4作出詳細(xì)的講解,并給出一個(gè)Hello,World式的面向表示的應(yīng) 用的例子。該應(yīng)用允許用戶輸入名字到HTML表單中(見(jiàn)圖4-1),并且在名字提交之后顯示一條問(wèn)候信息(見(jiàn)圖4―2)。

          Greeting Form

          圖4-1 問(wèn)候表單

          Response

          圖4-2 響應(yīng)

          這個(gè)Hello應(yīng)用包含了兩個(gè)Web組件,用于產(chǎn)生問(wèn)候信息和響應(yīng)。在本指南中,該應(yīng)用有兩個(gè)版本:一個(gè)是servlet版,名為Hello1,它的組件通過(guò)兩個(gè)servlet類(lèi)(GreetingServlet.javaResponseServlet.java)來(lái)實(shí)現(xiàn)。另一個(gè)是JSP版,名為Hello2,它的組件通過(guò)兩個(gè)JSP頁(yè)面(greeting.jspresponse.jsp)來(lái)實(shí)現(xiàn)。這兩個(gè)版本的例子展示了一個(gè)包含Web組件的應(yīng)用在大包、部署和運(yùn)行時(shí)所涉及到的任務(wù)。如果你是在線瀏覽本指南,請(qǐng)務(wù)必下載本指南的捆綁包,以獲得這個(gè)示例的源代碼。

          Web應(yīng)用歸檔文件

          如果要發(fā)布一個(gè)Web應(yīng)用,你可以將其打包到一個(gè)Web應(yīng)用歸檔文件(Web application archive,WAR)中,WAR與JAR類(lèi)似,都是用作Java類(lèi)庫(kù)的包。除了應(yīng)用的Web組件外,Web應(yīng)用的歸檔文件還包含其他的一些文件,包括:

          ·?? 服務(wù)器端的實(shí)用工具類(lèi)(如數(shù)據(jù)庫(kù)bean、購(gòu)物車(chē)等等)。這些類(lèi)通常與JavaBeans組件的結(jié)構(gòu)一致。

          ·?? 靜態(tài)Web表示內(nèi)容(如HTML,圖像和聲音文件等)

          ·?? 客戶端類(lèi)(applet和實(shí)用工具類(lèi))

          Web組件和靜態(tài)Web內(nèi)容文件叫做Web資源

          Web應(yīng)用的運(yùn)行可以通過(guò)一個(gè)WAR文件,或者通過(guò)一個(gè)同為WAR格式的解包目錄。

          WAR目錄結(jié)構(gòu)

          WAR的頂級(jí)目錄是該應(yīng)用的文檔根目錄。這個(gè)文檔根目錄下存放著JSP頁(yè)面、客戶端類(lèi)和歸檔文件,以及靜態(tài)Web資源。

          文檔根目錄下含有一個(gè)名為WEB-INF的子目錄,其中包含了以下文件和目錄:

          ·?? web.xml —— Web應(yīng)用的部署描述文件。

          ·?? 標(biāo)簽庫(kù)描述文件。

          ·?? classes —— 一個(gè)子目錄,包含了服務(wù)器端類(lèi):servlets,實(shí)用工具類(lèi)和JavaBeans組件。

          ·?? lib —— 一個(gè)子目錄,包含了庫(kù)(標(biāo)簽庫(kù)和所有作為服務(wù)器端類(lèi)的實(shí)用工具類(lèi))

          還可以創(chuàng)建應(yīng)用專(zhuān)用(application-specific)的子目錄(即包目錄),可以在文檔根目錄下創(chuàng)建,或者在WEB-INF/classes目錄下創(chuàng)建。

          指南示例的目錄結(jié)構(gòu)

          為了便于迭代開(kāi)發(fā)并且將Web應(yīng)用的源代碼與已編譯的文件分開(kāi),實(shí)例的源代碼存儲(chǔ)在每個(gè)應(yīng)用目錄mywebapp下,其結(jié)構(gòu)如下:

          ·?? build.xml—— Ant生成文件

          ·?? context.xml——可選應(yīng)用配置文件

          ·?? src —— servler和Javabeans組件的Java源代碼。

          ·?? web —— JSP頁(yè)面和HTML頁(yè)面、圖像。

          隨示例一起發(fā)布的Ant build文件(build.xml)中包含了一些目標(biāo) (target),用以在mywebappbuild子目錄中創(chuàng)建解包的WAR結(jié)構(gòu),將文件拷貝和編譯到那個(gè)目錄中,并且通過(guò)專(zhuān)門(mén)的Ant任務(wù)調(diào)用manager命令,來(lái)安裝、重新裝載、移除、部署和解部署應(yīng)用。該指南示例的Ant目標(biāo)是:

          ·?? prepare(準(zhǔn)備) —— 創(chuàng)建build目錄和WAR子目錄。

          ·?? build(編譯) —— 編譯和拷貝mywebapp Web應(yīng)用文件到build目錄下。

          ·?? install(安裝)—— 使用Ant install任務(wù)通知Tomcat安裝應(yīng)用(見(jiàn)安裝Web應(yīng)用)。

          ·?? reload(重新裝載)—— 使用Ant reload任務(wù)通知Tomcat重新裝載應(yīng)用(見(jiàn)更新Web應(yīng)用)。

          ·?? deploy(部署) —— 使用Ant deploy任務(wù)通知Tomcat部署應(yīng)用(見(jiàn)部署Web應(yīng)用)。

          ·?? undeploy(解除部署)——使用Ant undeploy任務(wù)通知Tomcat解除部署應(yīng)用(見(jiàn)解除部署Web應(yīng)用

          ·?? remove(移除) —— 使用 Ant remove任務(wù)通知Tomcat移除應(yīng)用(見(jiàn)移除Web應(yīng)用

          創(chuàng)建WAR

          手工的創(chuàng)建WAR文件有兩種方法:

          ·?? 使用隨J2SE SDK一起發(fā)布的JAR工具。只需簡(jiǎn)單地在指南示例的build目錄下執(zhí)行如下命令:

          jar cvf mywebapp.war .

          ·?? 使用Ant war任務(wù)

          這兩種方法都要求有創(chuàng)建好的Web應(yīng)用部署描述文件。

          配置Web應(yīng)用

          Web 應(yīng)用的配置是通過(guò)包含在Web應(yīng)用部署描述文件中的元素的設(shè)置來(lái)實(shí)現(xiàn)的。你可以使用文本編輯器來(lái)手工創(chuàng)建這些描述文件。接下來(lái)的章節(jié)將對(duì)你想配置的Web 應(yīng)用特征作一個(gè)簡(jiǎn)要的介紹。其中,許多的安全參數(shù)都可以在配置時(shí)指定,這些內(nèi)容在第18章可以看到。如果你想得到這些特征的完整列表和描述,參見(jiàn)Java Servlet規(guī)范。

          在接下來(lái)的幾節(jié)中,將給出一些示例來(lái)演示Hello,World應(yīng)用的配置過(guò)程。如果Hello,World沒(méi)有使用指定的配置特征,那么本節(jié)將給出其他的示例來(lái)展示部署描述文件的元素并描述指定這種特征的一般過(guò)程。



          注 意:描述符元素必須在部署描述文件中按照下列順序出現(xiàn):icon,display,description,distributable,context -param,filter,filter-mapping,listener,servlet,servlet-mapping,session-config,mime-mapping,welcome-file-list,error-page,taglib,resource-env-ref,resource-ref,security-contraint,login-config,seurity-role,env-entry.


          序言

          既然部署描述文件是一種XML文檔,它就需要一個(gè)序言。Web應(yīng)用的部署描述文件的序言如下所示:

          
                                
          Application 2.3//EN" "http://java.sun.com/dtd/web-
          app_2_3.dtd"> ?
          
                                
          Application 2.3//EN" "http://java.sun.com/dtd/web-
          app_2_3.dtd">? 
          ?

          別名路徑

          當(dāng)Tomcat收到一個(gè)請(qǐng)求時(shí),它必須決定使用哪個(gè)Web組件來(lái)處理請(qǐng)求。這一步是通過(guò)將包含在請(qǐng)求中的URL路徑映像到一個(gè)Web組件來(lái)實(shí)現(xiàn)的。URL路徑包含上下文根目錄(參見(jiàn)Installing Web Application,http://java.sun.com/webservices/docs/1.1/tutorial/doc/WebApp5.html#wp75667)和一個(gè)別名路徑。

          http://<host>:8080/context_root/alias_path 
          http://<host>:8080/context_root/alias_path 
          ?

          在servlet 可以被訪問(wèn)前,Web容器必須最少有一個(gè)該組件的別名路徑。別名路徑必須以一個(gè)“/”開(kāi)始,以一個(gè)字符串或者一個(gè)帶擴(kuò)展名的通配符(例如:*.jsp)結(jié) 束。既然Web容器自動(dòng)地映像到以*.jsp結(jié)束的別名路徑,你無(wú)需為JSP頁(yè)面指定別名路徑,除非你想通過(guò)一個(gè)名稱(chēng),而不是其文件名來(lái)引用JSP頁(yè)面。 在更新Web應(yīng)用中討論的實(shí)例中,問(wèn)候頁(yè)面有一個(gè)別名response.jsp,但它仍然是通過(guò)其文件名來(lái)引用的。

          在Web 部署描述文件中設(shè)置servlet版的Hello應(yīng)用的映像,必須添加下列servlet和servlet-mapping元素到Web應(yīng)用部署描述文件 中。為了定義JSP頁(yè)面的別名,必須替換在servlet元素中的servlet-class子元素和jsp-file子元素。

          ??greeting
          ??greeting
          ??no description
          ??GreetingServlet
          
                                
          ??response
          ??response
          ??no description
          ??ResponseServlet
          
                                
          ??greeting
          ??/greeting
          
                                
          ??response
          ??/response
           

          上下文和初始化參數(shù)

          同 一個(gè)WAR中的各Web組件共享一個(gè)表示它們的應(yīng)用上下文的對(duì)象(見(jiàn)訪問(wèn)Web上下文)。你可以傳遞參數(shù)到上下文或者Web組件。要實(shí)現(xiàn)這一點(diǎn),你必須添 加一個(gè)context-param或init-param元素到Web應(yīng)用部署描述文件中。context-param是頂級(jí)web-app元素的子元 素。init-param是servlet元素的子元素。下面的元素用于聲明一個(gè)上下文參數(shù),該參數(shù)設(shè)置在第17章中討論的示例的資源束:

          ??
          ????
          ??????javax.servlet.jsp.jstl.fmt.localizationContext
          ????
          ????messages.BookstoreMessages
          ??
          ??...
           

          事件監(jiān)聽(tīng)器

          要添加事件監(jiān)聽(tīng)器類(lèi),必須添加一個(gè)listener元素到Web應(yīng)用部署描述文件中。下面的元素描述了在第14章和第17章用到的監(jiān)聽(tīng)器類(lèi))。

          ??listeners.ContextListener
           

          過(guò)濾器映像

          Web 容器使用過(guò)濾器映像聲明來(lái)決定應(yīng)用于某個(gè)請(qǐng)求的過(guò)濾器,并且決定這些過(guò)濾器的順序。正如在別名路徑中描述的那樣,該容器將請(qǐng)求URL與一個(gè)servlet 相匹配。要決定引用哪個(gè)過(guò)濾器,容器通過(guò)servlet名或者URL模式來(lái)匹配過(guò)濾器映像聲明。過(guò)濾器被調(diào)用的順序就是過(guò)濾器映像聲明在過(guò)濾器映像列表中 出現(xiàn)的順序,過(guò)濾器映像聲明將請(qǐng)求URI與一個(gè)servlet匹配起來(lái)。

          要指定過(guò)濾器映像,必須添加一個(gè)filter和filter-mapping元素到Web應(yīng)用部署描述文件中。下面的元素用于聲明有序的過(guò)濾器,并將其映像到在第14章討論過(guò)的Receipt servlet:

          ??OrderFilter
          ??filters.OrderFilter
          
                                
          ??OrderFilter
          ??/receipt
           

          錯(cuò)誤映像

          可 以指定狀態(tài)代碼與Web資源之間的映像,其中的狀態(tài)代碼可以是一個(gè)HTTP響應(yīng)中返回的,也可以是由任何Web組件返回的一個(gè)Java編程語(yǔ)言異常中返回 的。要設(shè)置映像,必須添加一個(gè)元素到部署描述文件中。下面的元素用于將OederException映像到第14章 中使用的頁(yè)面errorpage.html。

          ??exception.OrderException
          ??/errorpage.html
           


          注意:你也可以為包含在WAR內(nèi)的JSP頁(yè)面定義錯(cuò)誤頁(yè)面。如果錯(cuò)誤頁(yè)面是同時(shí)為WAR和JSP頁(yè)面而定義的,則JSP頁(yè)面的錯(cuò)誤頁(yè)面居先。


          指向環(huán)境條目、資源環(huán)境條目或資源的引用

          如 果Web組件需要引用環(huán)境條目,資源環(huán)境條目或資源(如數(shù)據(jù)庫(kù)),必須通過(guò)在Web應(yīng)用部署描述文件中的,< resource-env-ref>或元素來(lái)聲明引用。下面的元素用于聲明一個(gè)指向某個(gè)數(shù)據(jù)源的引用,該 數(shù)據(jù)源在本指南關(guān)于Web技術(shù)的幾章中要用到。

          ??jdbc/BookDB
          ??javax.sql.DataSource
          ??Container
           


          安裝Web應(yīng)用

          上下文(context是映射到一個(gè)Web應(yīng)用的名稱(chēng)。例如,Hello1應(yīng)用的上下文是/hello1。為了將應(yīng)用安裝到Tomcat,需要通知Tomcat有一個(gè)新的可用上下文。

          可以使用Ant install任務(wù)來(lái)通知Tomcat有一個(gè)新的上下文。注意,在Tomcat重新啟動(dòng)之后,安裝好的應(yīng)用還不能使用。要永久地部署應(yīng)用,參見(jiàn)部署Web應(yīng)用

          Ant install任務(wù)告訴由url屬性指定的在本地運(yùn)行的管理器安裝一個(gè)應(yīng)用,其上下文由path屬性指定,其安裝位置包含了由war屬性指定的該Web應(yīng)用的文件。war屬性的值可以是一個(gè)WAR文件,如:

          jar:file:/path/to/bar.war!/ 或者是一個(gè)解包目錄:

          ?file:/path/to/foo。

          ??username="username" password="password" />

          username和password屬性將在Tomcat Web應(yīng)用管理程序中討論。

          這里無(wú)需提供一個(gè)war屬性,你可以使用config屬性來(lái)指定配置信息:

          ??path="mywebapp" config="file:build/context.xml"

          ??username="username" password="password"/>

          config屬性指出一個(gè)配置文件包含上下文條目的格式

          ??docBase="../docs/tutorial/examples/web/bookstore1/build"

          ??debug="0">

          注意,這個(gè)上下文條目通過(guò)它的docBase屬性隱式地指定了Web應(yīng)用文件的位置。

          本指南示例build文件包含一個(gè)Ant install target,它將調(diào)用Ant install 任務(wù)

          ??description="Install web application" depends="build">

          ??

          ????config="file:build/context.xml"

          ????username="${username}" password="${password}"/>

          Ant install任務(wù)要求Web應(yīng)用部署描述文件(web.xml)是可用的。所有的指南示例應(yīng)用都是隨一個(gè)部署描述文件一起發(fā)布的。

          To install the Hello1 application described in Web Application Life Cycle:

          要安裝Web應(yīng)用生命周期中描述的Hello1應(yīng)用,需按下列步驟:

          1. 在終端窗口中,轉(zhuǎn)到<JWSDP_HOME>/docs/tutorial/examples/web/hello1.

          2.確認(rèn)Tomcat已啟動(dòng)

          3.執(zhí)行ant install。install target通知Tomcat新的上下文是可用的。

          部署Web應(yīng)用

          如果Tomcat正在運(yùn)行,就可以使用Ant deploy任務(wù)永久地將一個(gè)上下文部署到Tomcat。

          ??

          ????war="file:/path/to/mywebapp.war"

          ????username="username" password="password" />

          不同于install任務(wù),install任務(wù)可以引用一個(gè)解包目錄,deploy任務(wù)需要一個(gè)WAR。該任務(wù)加載WAR到Tomcat并且啟動(dòng)應(yīng)用。也可以通過(guò)這個(gè)任務(wù)將其部署到一個(gè)遠(yuǎn)程服務(wù)器上。

          下面是其他一些可用的部署方法,但是它們要求重新啟動(dòng)Tomcat:

          ·?? 將Web應(yīng)用目錄或WAR拷貝到/webapps。

          ·?? 將包含了上下文條目的名為mywebapp.xml的配置文件拷貝到/webapps。上下文條目的格式在< JWSDP_HOME>/docs/tomcat/config/context.html中的 Server Configuration Reference里有描述。注意,上下文條目通過(guò)docBase屬性隱式地指定了Web應(yīng)用文件的位置。例如,下面是在第14章中討論的應(yīng)用的上下文條目:

          ??

          ????docBase="../docs/tutorial/examples/web/

          ??????bookstore1/build" debug="0">

          一些實(shí)例build文件包含一個(gè)像Ant deploy 任務(wù)一樣調(diào)用的Ant deploy 目標(biāo)

          列出已安裝和部署的Web應(yīng)用

          如果想列出當(dāng)前在Tomcat內(nèi)可使用所有Web應(yīng)用,你可以使用Ant list任務(wù):

           

          指南示例build文件包含一個(gè)像調(diào)用Ant list 任務(wù)一樣調(diào)用的Ant list 目標(biāo)

          還可以通過(guò)運(yùn)行Manager Application來(lái)查看列出的應(yīng)用:

          http://:8080/manager/list

          運(yùn)行Web應(yīng)用

          Web應(yīng)用是在Web瀏覽器引用映像到組件的URL時(shí)執(zhí)行的。一旦安裝了或者部署了Hello1應(yīng)用,便可通過(guò)將瀏覽器指向

          http://:8080/hello1/greeting 
          來(lái)運(yùn)行Web應(yīng)用。

          用運(yùn)行Tomcat的主機(jī)名替代。如果瀏覽器運(yùn)行在與Tomcat相同的主機(jī)上,就可以用localhost替代

          更新Web應(yīng)用

          在開(kāi)發(fā)期間,經(jīng)常需要對(duì)Web應(yīng)用進(jìn)行修改。在修改servlet之后,必須:

          1.重新編譯servlet類(lèi)。

          2.更新服務(wù)器上的應(yīng)用。

          3.重新在客戶端裝載URL。

          更新JSP頁(yè)面時(shí),無(wú)需重新編譯或重新裝載應(yīng)用,因?yàn)門(mén)omcat會(huì)自動(dòng)完成這些事情。

          為了嘗試這一特征,修改Hello應(yīng)用的servlet版本。例如,你可以將GreetingServlet返回的問(wèn)候信息修改為:

          Hi, my name is Duke. What's yours?

          更新文件的過(guò)程為:

          1.?? 編輯在源碼目錄/docs/tutorial/examples/web/hello1/src中的GreetingServlet.java文件。

          2. 運(yùn)行ant build任務(wù)。該任務(wù)將servlet重新編譯到build目錄中。

          更新服務(wù)器中的應(yīng)用這一過(guò)程取決于你是否使用Ant install任務(wù)來(lái)安裝或者使用Ant deploy任務(wù)來(lái)部署這個(gè)應(yīng)用。

          重新裝載Web應(yīng)用

          如果你已經(jīng)使用Ant install命令安裝了應(yīng)用,就可以使用Ant reload任務(wù)來(lái)更新服務(wù)器中的應(yīng)用:

          
                                
          ??username="username" password="password" /> 

          示例build文件包含一個(gè) Ant remove目標(biāo),該目標(biāo)調(diào)用 Ant remove任務(wù)。從而更新服務(wù)器中的Hello1應(yīng)用,執(zhí)行ant reload。為了觀察經(jīng)過(guò)更新的應(yīng)用,重新裝載客戶端的Hello1的URL。注意,reload任務(wù)只改變Java類(lèi),而不會(huì)改變Web.xml文件。為了重新裝載web.xml,需要將應(yīng)用刪除 (參見(jiàn)移除Web應(yīng)用)并重新安裝。

          在瀏覽器上你可以看到如圖4-3所示的屏幕:

          New Greeting

          圖4-3 新的問(wèn)候信息

          為了在該實(shí)例的JSP版本上嘗試這一特性,首先建立和部署JSP版的Hello應(yīng)用:

          1. 在終端窗口中,轉(zhuǎn)到

          <JWSDP_HOME>/docs/tutorial/examples/web/hello2.

          2.??? 運(yùn)行ant buildbuild目標(biāo)將產(chǎn)生所有必需的編譯并且拷貝文件到

          <JWSDP_HOME>/docs/tutorial/examples/web/hello2/build 目錄。

          3. 運(yùn)行ant installinstall目標(biāo)將build目錄拷貝到/webappsbuild并通知Tomcat有新的應(yīng)用。

          修改某一個(gè)JSP文件。然后運(yùn)行ant build將經(jīng)過(guò)修改的文件拷貝到docs/tutorial/examples/web/hello2/build。記住,這里無(wú)需重新裝載服務(wù)器中的應(yīng)用,因?yàn)楫?dāng)某個(gè)JSP文件被修改時(shí),Tomcat會(huì)自動(dòng)檢測(cè)到這一情況。要查看經(jīng)過(guò)修改的應(yīng)用, 需重新裝載客戶端的Hello2的URL。

          重新部署Web應(yīng)用

          如果已經(jīng)通過(guò)使用Ant deploy任務(wù)部署了應(yīng)用,就可以通過(guò)接連使用Ant undeploy任務(wù)(見(jiàn)解除部署Web應(yīng)用)和Ant deploy任務(wù)來(lái)更新這個(gè)應(yīng)用。

          移除Web應(yīng)用

          如果想從服務(wù)中移除已安裝的Web應(yīng)用,可以調(diào)用 Ant remove任務(wù):

          
                                
          ??username="username" password="password" /> 

          示例build文件包含一個(gè) Ant remove目標(biāo),該目標(biāo)調(diào)用 Ant remove務(wù)。

          解除部署Web應(yīng)用

          如果想移除一個(gè)已部署的Web應(yīng)用,可以使用Ant undeploy任務(wù):

          
                                
          ??username="username" password="password" /> 

          一些實(shí)例build文件包含一個(gè)Ant undeploy目標(biāo),該目標(biāo)調(diào)用Ant undeploy任務(wù)

          Web應(yīng)用的國(guó)際化和本地化

          所謂的國(guó)際化是指使得應(yīng)用能夠支持各種語(yǔ)言和數(shù)據(jù)格式的過(guò)程。所謂本地化,是指使得一個(gè)國(guó)際化的應(yīng)用能夠支持某種特定的或者本地的語(yǔ)言的過(guò)程。雖然所有客戶端用戶接口都應(yīng)該被國(guó)際化和本地化,但是國(guó)際化和本地化對(duì)于Web應(yīng)用來(lái)說(shuō)尤其重要,因?yàn)閃eb本身就是無(wú)所不及的。如果想要很好地鳥(niǎo)瞰一下國(guó)際化與本地化問(wèn)題,參見(jiàn)

          http://java.sun.com/docs/books/tutorial/i18n/index.html

          有兩種方法可以用于對(duì)Web應(yīng)用進(jìn)行國(guó)際化:

          ·?? 在每個(gè)目標(biāo)位置中提供一個(gè)JSP頁(yè)面,并且使用一個(gè)控制器servlet來(lái)發(fā)送請(qǐng)求到適當(dāng)?shù)捻?yè)面上(取決于被請(qǐng)求的位置)。如果需要對(duì)一個(gè)頁(yè)面或者一個(gè)完 整的Web應(yīng)用的數(shù)據(jù)進(jìn)行國(guó)際化,這種方法比較有用。

          ·?? 將頁(yè)面上所有的本地敏感的數(shù)據(jù) (例如錯(cuò)誤信息,串字符或按鈕標(biāo)簽) 分離到資源束內(nèi),然后訪問(wèn)這些數(shù)據(jù),來(lái)獲取響應(yīng)的翻譯過(guò)來(lái)的信息并將其插入到頁(yè)面當(dāng)中。這樣一來(lái),就不是在代碼中直接創(chuàng)建字符串,而是創(chuàng)建一個(gè)包含了翻譯 過(guò)來(lái)的信息的資源束,然后使用相應(yīng)的關(guān)鍵字從該資源束中讀出翻譯過(guò)來(lái)的信息。資源束可以由一個(gè)文本文件(屬性資源束)或一個(gè)包含了映像的類(lèi)(列表資源束) 來(lái)支持。

          在 下面的關(guān)于Web技術(shù)的幾章中,Duke's Bookstore實(shí)例被分別國(guó)際化和本地化成英語(yǔ)和西班牙語(yǔ)。關(guān)鍵字-值對(duì)包含在名為message.BookMessage_*.class的列表資 源束。為了了解在資源束中的關(guān)鍵字-值對(duì)是怎樣的,請(qǐng)看在文件messages.BookMessages.java中添加的幾行:

          {"TitleCashier", "Cashier"},

          {"TitleBookDescription", "Book Description"},

          {"Visitor", "You are visitor number "},

          {"What", "What We"re Reading"},

          {"Talk", " talks about how Web components can transform the way

          you develop applications for the Web. This is a must read for

          any self respecting Web developer!"},

          {"Start", "Start Shopping"},

          為了獲得對(duì)應(yīng)于某個(gè)給定用戶的正確字符串,Web組件從請(qǐng)求中獲取位置(由瀏覽器的語(yǔ)言首選項(xiàng)設(shè)定),為那個(gè)位置打開(kāi)資源束,然后將該資源束作為會(huì)話屬性保存:

          ResourceBundle messages = (ResourceBundle)session.

          ??getAttribute("messages");

          ??if (messages == null) {

          ????Locale locale=request.getLocale();

          ????messages = ResourceBundle.getBundle("WebMessages",

          ??????locale);

          ????session.setAttribute("messages", messages);

          ??}

          Web組件從會(huì)話中獲取資源束:

          ResourceBundle messages =

          ??(ResourceBundle)session.getAttribute("messages");

          然后用下面的語(yǔ)句查找與關(guān)鍵字TitleCashier相關(guān)的字符串:

          messages.getString("TitleCashier");

          上面對(duì)國(guó)際化Web應(yīng)用的介紹非常簡(jiǎn)要。如果要了解更多該主題的相關(guān)信息,參見(jiàn)Java BluePrints:

          http://java.sun.com/blueprints

          posted @ 2005-11-09 18:01 svg_007 閱讀(287) | 評(píng)論 (0)編輯 收藏

          下一步的學(xué)習(xí)計(jì)劃

          今天確定了WEB開(kāi)發(fā)的框架。確定采用XMLC+Tomcat+JavaBean的框架。從現(xiàn)在開(kāi)始關(guān)注這方面問(wèn)題!

          posted @ 2005-11-09 17:55 svg_007 閱讀(210) | 評(píng)論 (1)編輯 收藏

          JSF與Struts的異同

          Struts和JSF/Tapestry都屬于表現(xiàn)層框架,這兩種分屬不同性質(zhì)的框架,后者是一種事件驅(qū)動(dòng)型的組件模型,而Struts只是單純的MVC模式框架,老外總是急吼吼說(shuō)事件驅(qū)動(dòng)型就比MVC模式框架好,何以見(jiàn)得,我們下面進(jìn)行詳細(xì)分析比較一下到底是怎么回事?

            首先事件是指從客戶端頁(yè)面(瀏覽器)由用戶操作觸發(fā)的事件,Struts使用Action來(lái)接受瀏覽器表單提交的事件,這里使用了Command模式,每個(gè)繼承Action的子類(lèi)都必須實(shí)現(xiàn)一個(gè)方法execute。

            在struts中,實(shí)際是一個(gè)表單Form對(duì)應(yīng)一個(gè)Action類(lèi)(或DispatchAction),換一句話說(shuō):在Struts中實(shí)際是一 個(gè)表單只能對(duì)應(yīng)一個(gè)事件,struts這種事件方式稱(chēng)為application event,application event和component event相比是一種粗粒度的事件。

            struts重要的表單對(duì)象ActionForm是一種對(duì)象,它代表了一種應(yīng)用,這個(gè)對(duì)象中至少包含幾個(gè)字段,這些字段是Jsp頁(yè)面表單中的 input字段,因?yàn)橐粋€(gè)表單對(duì)應(yīng)一個(gè)事件,所以,當(dāng)我們需要將事件粒度細(xì)化到表單中這些字段時(shí),也就是說(shuō),一個(gè)字段對(duì)應(yīng)一個(gè)事件時(shí),單純使用 Struts就不太可能,當(dāng)然通過(guò)結(jié)合JavaScript也是可以轉(zhuǎn)彎實(shí)現(xiàn)的。

            而這種情況使用JSF就可以方便實(shí)現(xiàn),

          <h:inputText id="userId" value="#{login.userId}">
            <f:valueChangeListener type="logindemo.UserLoginChanged" />
          </h:inputText>

            #{login.userId}表示從名為login的JavaBean的getUserId獲得的結(jié)果,這個(gè)功能使用struts也可以實(shí)現(xiàn),name="login" property="userId"

            關(guān)鍵是第二行,這里表示如果userId的值改變并且確定提交后,將觸發(fā)調(diào)用類(lèi)UserLoginChanged的processValueChanged(...)方法。

            JSF可以為組件提供兩種事件:Value Changed和 Action. 前者我們已經(jīng)在上節(jié)見(jiàn)識(shí)過(guò)用處,后者就相當(dāng)于struts中表單提交Action機(jī)制,它的JSF寫(xiě)法如下:

          <h:commandButton id="login" commandName="login">
            <f:actionListener type=”logindemo.LoginActionListener” />
          </h:commandButton>

            從代碼可以看出,這兩種事件是通過(guò)Listerner這樣觀察者模式貼在具體組件字段上的,而Struts此類(lèi)事件是原始的一種表單提交 Submit觸發(fā)機(jī)制。如果說(shuō)前者比較語(yǔ)言化(編程語(yǔ)言習(xí)慣做法類(lèi)似Swing編程);后者是屬于WEB化,因?yàn)樗莵?lái)自Html表單,如果你起步是從 Perl/PHP開(kāi)始,反而容易接受Struts這種風(fēng)格。

          基本配置

            Struts和JSF都是一種框架,JSF必須需要兩種包JSF核心包、JSTL包(標(biāo)簽庫(kù)),此外,JSF還將使用到Apache項(xiàng)目的一些commons包,這些Apache包只要部署在你的服務(wù)器中既可。

            JSF包下載地址:http://java.sun.com/j2ee/javaserverfaces/download.html選擇其中Reference Implementation。

            JSTL包下載在http://jakarta.apache.org/site/downloads/downloads_taglibs-standard.cgi

            所以,從JSF的驅(qū)動(dòng)包組成看,其開(kāi)源基因也占據(jù)很大的比重,JSF是一個(gè)SUN伙伴們工業(yè)標(biāo)準(zhǔn)和開(kāi)源之間的一個(gè)混血兒。

            上述兩個(gè)地址下載的jar合并在一起就是JSF所需要的全部驅(qū)動(dòng)包了。與Struts的驅(qū)動(dòng)包一樣,這些驅(qū)動(dòng)包必須位于Web項(xiàng)目的WEB-INF/lib,和Struts一樣的是也必須在web.xml中有如下配置:

          <web-app>
            <servlet>
              <servlet-name>Faces Servlet</servlet-name>
              <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
              <load-on-startup>1</load-on-startup>
            </servlet>

            <servlet-mapping>
              <servlet-name>Faces Servlet</servlet-name>
              <url-pattern>*.faces</url-pattern>
            </servlet-mapping>
          </web-app>

            這里和Struts的web.xml配置何其相似,簡(jiǎn)直一模一樣。

            正如Struts的struts-config.xml一樣,JSF也有類(lèi)似的faces-config.xml配置文件:


          <faces-config>
            <navigation-rule>
              <from-view-id>/index.jsp</from-view-id>
              <navigation-case>
                <from-outcome>login</from-outcome>
                <to-view-id>/welcome.jsp</to-view-id>
              </navigation-case>
            </navigation-rule>

            <managed-bean>
              <managed-bean-name>user</managed-bean-name>
              <managed-bean-class>com.corejsf.UserBean</managed-bean-class>
              <managed-bean-scope>session</managed-bean-scope>
            </managed-bean>
          </faces-config>

           

            在Struts-config.xml中有ActionForm Action以及Jsp之間的流程關(guān)系,在faces-config.xml中,也有這樣的流程,我們具體解釋一下Navigation:

            在index.jsp中有一個(gè)事件:

          <h:commandButton label="Login" action="login" />

            action的值必須匹配form-outcome值,上述Navigation配置表示:如果在index.jsp中有一個(gè)login事件,那么事件觸發(fā)后下一個(gè)頁(yè)面將是welcome.jsp

            JSF有一個(gè)獨(dú)立的事件發(fā)生和頁(yè)面導(dǎo)航的流程安排,這個(gè)思路比struts要非常清晰。

            managed-bean類(lèi)似Struts的ActionForm,正如可以在struts-config.xml中定義ActionForm的scope一樣,這里也定義了managed-bean的scope為session。

            但是如果你只以為JSF的managed-bean就這點(diǎn)功能就錯(cuò)了,JSF融入了新的Ioc模式/依賴性注射等技術(shù)。

          Ioc模式

            對(duì)于Userbean這樣一個(gè)managed-bean,其代碼如下:

          public class UserBean {
            private String name;
            private String password;

            // PROPERTY: name
            public String getName() { return name; }
            public void setName(String newValue) { name = newValue; }

            // PROPERTY: password
            public String getPassword() { return password; }
            public void setPassword(String newValue) { password = newValue; }
          }

          <managed-bean>
            <managed-bean-name>user</managed-bean-name>
            <managed-bean-class>com.corejsf.UserBean</managed-bean-class>
            <managed-bean-scope>session</managed-bean-scope>

            <managed-property>
              <property-name>name</property-name>
              <value>me</value>
            </managed-property>

            <managed-property>
              <property-name>password</property-name>
              <value>secret</value>
            </managed-property>
          </managed-bean>

            faces-config.xml這段配置其實(shí)是將"me"賦值給name,將secret賦值給password,這是采取Ioc模式中的Setter注射方式

          Backing Beans

            對(duì)于一個(gè)web form,我們可以使用一個(gè)bean包含其涉及的所有組件,這個(gè)bean就稱(chēng)為Backing Bean, Backing Bean的優(yōu)點(diǎn)是:一個(gè)單個(gè)類(lèi)可以封裝相關(guān)一系列功能的數(shù)據(jù)和邏輯。

            說(shuō)白了,就是一個(gè)Javabean里包含其他Javabean,互相調(diào)用,屬于Facade模式或Adapter模式。


            對(duì)于一個(gè)Backing Beans來(lái)說(shuō),其中包含了幾個(gè)managed-bean,managed-bean一定是有scope的,那么這其中的幾個(gè)managed-beans如何配置它們的scope呢?

          <managed-bean>
            ...
            <managed-property>
              <property-name>visit</property-name>
              <value>#{sessionScope.visit}</value>
            </managed-property>

            這里配置了一個(gè)Backing Beans中有一個(gè)setVisit方法,將這個(gè)visit賦值為session中的visit,這樣以后在程序中我們只管訪問(wèn)visit對(duì)象,從中獲取 我們希望的數(shù)據(jù)(如用戶登陸注冊(cè)信息),而visit是保存在session還是application或request只需要配置既可。

          UI界面

            JSF和Struts一樣,除了JavaBeans類(lèi)之外,還有頁(yè)面表現(xiàn)元素,都是是使用標(biāo)簽完成的,Struts也提供了struts-faces.tld標(biāo)簽庫(kù)向JSF過(guò)渡。

            使用Struts標(biāo)簽庫(kù)編程復(fù)雜頁(yè)面時(shí),一個(gè)最大問(wèn)題是會(huì)大量使用logic標(biāo)簽,這個(gè)logic如同if語(yǔ)句,一旦寫(xiě)起來(lái),搞的JSP頁(yè)面象俄羅斯方塊一樣,但是使用JSF標(biāo)簽就簡(jiǎn)潔優(yōu)美:

          <jia:navigatorItem name="inbox" label="InBox"
            icon="/images/inbox.gif"
            action="inbox"
            disabled="#{!authenticationBean.inboxAuthorized}"/>

            如果authenticationBean中inboxAuthorized返回是假,那么這一行標(biāo)簽就不用顯示,多干凈利索!

            先寫(xiě)到這里,我會(huì)繼續(xù)對(duì)JSF深入比較下去,如果研究過(guò)Jdon框架的人,可能會(huì)發(fā)現(xiàn),Jdon框架的jdonframework.xml中 service配置和managed-bean一樣都使用了依賴注射,看來(lái)對(duì)Javabean的依賴注射已經(jīng)迅速地成為一種新技術(shù)象征,如果你還不了解 Ioc模式,趕緊補(bǔ)課。

          附Jsf核心教程一個(gè)JSF案例:login.rar

          posted @ 2005-11-08 14:35 svg_007 閱讀(186) | 評(píng)論 (0)編輯 收藏

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(2)

          隨筆檔案

          搜索

          最新評(píng)論

          • 1.?re: 下一步的學(xué)習(xí)計(jì)劃
          • 哥們,現(xiàn)在有多少人在用xmlc框架阿?估計(jì)沒(méi)有人用了吧。你有這方面的資料嗎?有的話給我發(fā)一份,謝謝了阿。我的郵箱abcdefghijk_a@163.com
          • --關(guān)注

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 札达县| 察隅县| 永安市| 怀仁县| 同德县| 府谷县| 普定县| 海门市| 织金县| 墨江| 保定市| 余姚市| 大安市| 抚顺县| 高青县| 海城市| 交口县| 迁西县| 石家庄市| 昌吉市| 乡城县| 谷城县| 左贡县| 府谷县| 罗田县| 娄烦县| 治县。| 天气| 建阳市| 游戏| 梅河口市| 麻阳| 宜黄县| 万宁市| 甘南县| 周宁县| 宿州市| 汕尾市| 洪江市| 吴川市| 永丰县|