




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1第十講Servlet程序設(shè)計(jì)鄭莉2目錄10.1Java網(wǎng)絡(luò)程序設(shè)計(jì)的根本概念——看MOOC:Java程序設(shè)計(jì)進(jìn)階第四~五章10.2Servlet根底10.3Servlet的生命周期10.4與客戶端交互10.5客戶端跟蹤10.6協(xié)作與通訊10.7程序舉例10.8本章小結(jié)34網(wǎng)絡(luò)將世界聯(lián)系在一起,使世界變得更加豐富多彩。同時(shí)網(wǎng)絡(luò)互連是一個(gè)內(nèi)容豐富而復(fù)雜的主題,所以這方面的程序設(shè)計(jì)涉及面很廣且不易掌握與其他語(yǔ)言相比,Java語(yǔ)言在網(wǎng)絡(luò)應(yīng)用程序方面具有一定的優(yōu)勢(shì)。Java提供了很多內(nèi)置的網(wǎng)絡(luò)功能,使得基于Internet和Web的應(yīng)用開(kāi)發(fā)變得更加容易10.1Java網(wǎng)絡(luò)程序設(shè)計(jì)的根本概念510.1.1協(xié)議所有使用或?qū)崿F(xiàn)某種Internet效勞的程序都必須遵從一個(gè)或多個(gè)網(wǎng)絡(luò)協(xié)議,這種協(xié)議很多,而IP、TCP、UDP是最為根本的三種協(xié)議,是所有其它協(xié)議的根底IP〔InternetProtocol,Internet協(xié)議〕是最底層的協(xié)議定義了數(shù)據(jù)按照數(shù)據(jù)報(bào)〔Datagram,一種自帶尋址信息的、獨(dú)立地從數(shù)據(jù)源走到終點(diǎn)的數(shù)據(jù)包〕傳輸?shù)母袷胶鸵?guī)那么TCP〔TransportControlProtocol,傳輸控制協(xié)議〕建立在IP之上,定義了網(wǎng)絡(luò)上程序到程序的數(shù)據(jù)傳輸格式和規(guī)那么,提供了IP數(shù)據(jù)包的傳輸確認(rèn)、喪失數(shù)據(jù)包的重新請(qǐng)求、將收到的數(shù)據(jù)包按照它們的發(fā)送次序重新裝配的機(jī)制是面向連接的協(xié)議,在開(kāi)始數(shù)據(jù)傳輸之前,必須先建立明確的連接UDP〔UserDatagramProtocol,用戶數(shù)據(jù)報(bào)協(xié)議〕與TCP相似,比TCP具有更好的傳輸效率。不可靠的,不保證數(shù)據(jù)的傳輸,也不提供重新排列次序或重新請(qǐng)求功能,是一種無(wú)連接協(xié)議10.1Java網(wǎng)絡(luò)程序設(shè)計(jì)的根本概念6HTTP協(xié)議〔HyperTextTransferProtocol〕是Internet眾多協(xié)議中的一種,表示超文本傳輸協(xié)議,它構(gòu)成了WWW的根底具有簡(jiǎn)單快速、靈活、無(wú)狀態(tài)、無(wú)連接等特點(diǎn)基于請(qǐng)求〔Request〕/響應(yīng)〔Response〕模式。其工作過(guò)程如下首先客戶端與效勞器建立連接然后客戶端發(fā)送一個(gè)請(qǐng)求給效勞器效勞器接到請(qǐng)求后,給予相應(yīng)的響應(yīng)信息;最后關(guān)閉連接,完成一次操作10.1.1協(xié)議(續(xù))
——HTTP協(xié)議10.1Java網(wǎng)絡(luò)程序設(shè)計(jì)的根本概念7客戶端發(fā)送給效勞器的請(qǐng)求有很多類型,被稱為方法,其中最常用的是GET、POSTGET方法用來(lái)從效勞器讀取信息,比方從效勞器讀取文件、表格、數(shù)據(jù)庫(kù)查詢結(jié)果等POST方法用來(lái)向效勞器傳送信息,比方把信用卡號(hào)、表格、存儲(chǔ)于數(shù)據(jù)庫(kù)的數(shù)據(jù)等傳送到效勞器HEAD方法用來(lái)讀取效勞器響應(yīng)頭〔ResponseHead〕;得到諸如文件大小,文件最后修改時(shí)間,效勞器類型等信息PUT方法將文件直接傳到效勞器DELETE方法將文件直接從效勞器刪除TRACE方法用來(lái)協(xié)助程序調(diào)試OPTIONS方法用來(lái)查詢效勞器所支持的方法10.1Java網(wǎng)絡(luò)程序設(shè)計(jì)的根本概念10.1.1協(xié)議(續(xù))
——HTTP協(xié)議中客戶端發(fā)送給效勞器的請(qǐng)求810.1.2關(guān)于URIURI〔UniformResourceIdentifier,統(tǒng)一資源標(biāo)識(shí)符〕HTTP協(xié)議用URI標(biāo)識(shí)定位網(wǎng)絡(luò)上的數(shù)據(jù)如果知道了公布在網(wǎng)絡(luò)上的某個(gè)HTML文件的URI,不管文件位于什么地方,都可以通過(guò)HTTP訪問(wèn)該文檔通常所說(shuō)的URL是URI的一種10.1Java網(wǎng)絡(luò)程序設(shè)計(jì)的根本概念9URL類Java語(yǔ)言提供了URL類讓我們能在源代碼層使用URL有六個(gè)構(gòu)造方法,其中最簡(jiǎn)單的是URL(Stringurl)。每個(gè)URL對(duì)象都封裝了資源的標(biāo)識(shí)符和協(xié)議處理程序,可以調(diào)用URL的方法來(lái)提取URL的組件把URL對(duì)象作為AppletContext接口的showDocument方法的參數(shù),就可以使執(zhí)行applet的瀏覽器顯示URL所指定的資源10.1.2關(guān)于URI(續(xù))
——URL類10.1Java網(wǎng)絡(luò)程序設(shè)計(jì)的根本概念10applet瀏覽指定URL舉例:ShowDocument.javaimport.*;importjava.util.*;importjava.awt.*;importjava.awt.event.*;importjava.applet.AppletContext;importjavax.swing.*;importjavax.swing.event.*;publicclassShowDocumentextendsJApplet{ publicvoidinit(){ JButtongoButton=newJButton("Linktosohu"); ContainermyContainer=getContentPane(); myContainer.add(newJLabel("LinktoSOHU"),BorderLayout.NORTH); myContainer.add(goButton,BorderLayout.SOUTH); goButton.addActionListener(newButtonListener()); }
10.1Java網(wǎng)絡(luò)程序設(shè)計(jì)的根本概念10.1.2關(guān)于URI(續(xù))
——例10-111classButtonListenerimplementsActionListener{ publicvoidactionPerformed(ActionEvente){ try{ URLnewDocument=newURL("://sohu"); AppletContextbrowser=getAppletContext(); browser.showDocument(newDocument); } catch(ExceptionURLException){} } }}10.1Java網(wǎng)絡(luò)程序設(shè)計(jì)的根本概念10.1.2關(guān)于URI(續(xù))
——例10-11210.1.3基于套接字的有連接通信基于套接字(socket)的有連接通信使用TCP協(xié)議一個(gè)socket必須在發(fā)送數(shù)據(jù)之前與目的地的socket取得連接一旦連接建立了,sockets就可以使用一個(gè)流接口完成翻開(kāi)-讀-寫-關(guān)閉,所有的發(fā)送的信息都會(huì)在另一端以同樣的順序被接收面向連接的操作比無(wú)連接的操作效率低,但是數(shù)據(jù)的平安性高10.1Java網(wǎng)絡(luò)程序設(shè)計(jì)的根本概念13用Java建立簡(jiǎn)單的效勞器程序需要五個(gè)步驟Step1:創(chuàng)立ServerSocket對(duì)象ServerSocketmyServer=newServerSocket(intport,intbacklog);Port指定一個(gè)可用的端口號(hào),用來(lái)定位效勞器上的效勞器應(yīng)用程序backlog指定能夠連接到效勞器的最多客戶數(shù)。連接客戶到達(dá)由backlog指定的最大客戶數(shù)量時(shí),效勞器將拒絕客戶連接Step2:通過(guò)ServerSocket的accept方法監(jiān)聽(tīng)客戶連接,效勞器無(wú)限期的監(jiān)聽(tīng)客戶連接Socketconnection=myServer.accept();有一個(gè)客戶連接時(shí),將產(chǎn)生并返回一個(gè)socket10.1Java網(wǎng)絡(luò)程序設(shè)計(jì)的根本概念10.1.3基于套接字的有連接通信(續(xù))
——效勞器端14Step3:通過(guò)Socket的方法getInputStream和getOutputStream獲取InputStream和OutputStream對(duì)象;通常將其他流類型和它們聯(lián)系起來(lái),如:ObjectInputStreaminput=newObjectInputStream(connection.getInputStream());ObjectOutputStreamoutput=newObjectOutputStream(connection.getOutputStream());Step4:客戶和效勞器通過(guò)OutputStream和InputStream對(duì)象進(jìn)行通信Step5:通信傳輸完畢,效勞器通過(guò)調(diào)用流和套接字的close方法關(guān)閉連接10.1Java網(wǎng)絡(luò)程序設(shè)計(jì)的根本概念10.1.3基于套接字的有連接通信(續(xù))
——效勞器端15在客戶端建立簡(jiǎn)單連接的思路類似,可分為四步Step1:建立一個(gè)Socket,實(shí)現(xiàn)與效勞器的連接Socketconnection=newSocket(InetAddressaddress,intport);address:效勞器IP地址。port:端口號(hào)連接成功,將返回一個(gè)Socket,否那么產(chǎn)生異常Step2:通過(guò)getInputStream和getOutputStream分別獲取Socket的InputStream和OutputStream的引用。同樣,也可以將其他流類型與InputStream和OutputStream聯(lián)系起來(lái)Step3:客戶與效勞器通過(guò)InputStream和OutputStream進(jìn)行通信Step4:傳輸完畢后,通過(guò)調(diào)用流和套接字的close方法關(guān)閉連接10.1Java網(wǎng)絡(luò)程序設(shè)計(jì)的根本概念10.1.3基于套接字的有連接通信(續(xù))
——客戶端16數(shù)據(jù)報(bào)通信(DatagramCommunication)使用用戶數(shù)據(jù)報(bào)協(xié)議(UserDatagramProtocol,UDP)與TCP不同的一種協(xié)議不能保證數(shù)據(jù)會(huì)被成功地送達(dá),也不保證數(shù)據(jù)抵達(dá)的次序與送出的次序相同,所以也被稱為“不可靠的通信協(xié)議”,雖然可靠性不高,但是它的速度很快,所以有些場(chǎng)合也有很大的用處效勞器通過(guò)DatagramSocket接收或發(fā)送信息,這些信息以DatagramPackets的形式存在DatagramSocketmySocket=newDatagramSocket(intport);port表示端口,上述語(yǔ)句將效勞器綁定到一個(gè)可以從客戶端接收packet的端口上,如果綁定失敗,將產(chǎn)生SocketException異常10.1Java網(wǎng)絡(luò)程序設(shè)計(jì)的根本概念10.1.4數(shù)據(jù)報(bào)通信17客戶端應(yīng)用程序的工作流程Step1:通過(guò)創(chuàng)立一個(gè)DatagramSocket對(duì)象來(lái)建立數(shù)據(jù)報(bào)通訊的Socket。有如下兩種構(gòu)造方法publicDatagramSocket()構(gòu)造一個(gè)數(shù)據(jù)報(bào)socket,并使其與本地主機(jī)任一可用的端口連接。假設(shè)打不開(kāi)socket那么拋出SocketException異常。publicDatagramSocket(intport)構(gòu)造一個(gè)數(shù)據(jù)報(bào)socket,并使其與本地主機(jī)指定的端口連接。假設(shè)打不開(kāi)socket或socket無(wú)法與指定的端口連接那么拋出SocketException異常10.1Java網(wǎng)絡(luò)程序設(shè)計(jì)的根本概念10.1.4數(shù)據(jù)報(bào)通信(續(xù))
——客戶端18Step2:用DatagramPacket類來(lái)創(chuàng)立一個(gè)數(shù)據(jù)報(bào)包,用來(lái)實(shí)現(xiàn)無(wú)連接的包傳送效勞DatagramPacket對(duì)象封裝了數(shù)據(jù)報(bào)包的數(shù)據(jù)(bufferedarray[],包長(zhǎng)度(length),目標(biāo)地址(address),目標(biāo)端口(port);length必須小于等于bufferedarry.lengthDatagramPacket〔bytebufferedarray[],intlength,InetAddressaddress,intport〕DatagramPacket類提供了四個(gè)方法來(lái)獲取信息publicbyte[]getData()返回一個(gè)字節(jié)數(shù)組,包含收到或要發(fā)送的數(shù)據(jù)報(bào)中的數(shù)據(jù)publicintgetLength()返回發(fā)送或接收到的數(shù)據(jù)的長(zhǎng)度publicInetAddressgetAddress()返回一個(gè)發(fā)送或接收此數(shù)據(jù)報(bào)包文的機(jī)器的IP地址publicintgetPort()返回發(fā)送或接收數(shù)據(jù)報(bào)的遠(yuǎn)程主機(jī)的端口號(hào)10.1Java網(wǎng)絡(luò)程序設(shè)計(jì)的根本概念10.1.4數(shù)據(jù)報(bào)通信(續(xù))
——客戶端19Step3:調(diào)用DatagramSocket對(duì)象的send(DatagramPacketp)方法發(fā)送數(shù)據(jù)報(bào)文包Step4:調(diào)用DatagramSocket對(duì)象的receive(DatagramPacketp)方法接收從效勞器返回的結(jié)果數(shù)據(jù)報(bào)文包該DatagramPacket對(duì)象用到另一種構(gòu)造方法,只需指明存放接收的數(shù)據(jù)報(bào)的緩沖區(qū)和長(zhǎng)度DatagramPacket〔bytebufferedarray[],intlength〕receive方法會(huì)一直阻塞,直到收到一個(gè)數(shù)據(jù)報(bào)文包,此時(shí)DatagramPacket的緩沖區(qū)中包含的就是接收到的數(shù)據(jù),也包含發(fā)送者的IP地址,發(fā)送者機(jī)器上的端口號(hào)等信息Step5:處理接收緩沖區(qū)內(nèi)的數(shù)據(jù),獲取效勞結(jié)果Step6:通訊完成后,使用DatagramSocket對(duì)象的close()方法來(lái)關(guān)閉數(shù)據(jù)報(bào)通訊Socket10.1Java網(wǎng)絡(luò)程序設(shè)計(jì)的根本概念10.1.4數(shù)據(jù)報(bào)通信(續(xù))
——客戶端20效勞器端應(yīng)用程序的工作流程與客戶端應(yīng)用程序的通訊過(guò)程非常相似建立數(shù)據(jù)報(bào)通訊DatagramSocket構(gòu)建數(shù)據(jù)報(bào)文包DatagramPacket接收數(shù)據(jù)報(bào)和發(fā)送數(shù)據(jù)報(bào),處理接收緩沖區(qū)內(nèi)的數(shù)據(jù)通訊完畢后,關(guān)閉數(shù)據(jù)報(bào)通訊Socket不同的是,效勞器應(yīng)用程序要面向網(wǎng)絡(luò)中的所有計(jì)算機(jī),所以效勞器應(yīng)用程序收到一個(gè)包文后要分析它,得到數(shù)據(jù)報(bào)的源地址信息,這樣才能創(chuàng)立正確的返回結(jié)果報(bào)文給客戶機(jī)10.1Java網(wǎng)絡(luò)程序設(shè)計(jì)的根本概念10.1.4數(shù)據(jù)報(bào)通信(續(xù))
——效勞器端2110.1.5ServletServlet是用java技術(shù)來(lái)實(shí)現(xiàn)CGI〔CommonGatewayInterface,通用網(wǎng)關(guān)接口〕功能的編程介于瀏覽器〔或其他HTTP客戶端〕與效勞器之間,起到橋梁的作用。具體作用為:讀取客戶端發(fā)送的數(shù)據(jù)獲取客戶請(qǐng)求〔request〕中所包含的信息產(chǎn)生響應(yīng)結(jié)果,并將結(jié)果包含到一個(gè)文件中,比方HTML文件中設(shè)置HTTP響應(yīng)參數(shù),比方告訴瀏覽器,文件類型為HTML將文件返回給客戶端10.1Java網(wǎng)絡(luò)程序設(shè)計(jì)的根本概念22Servlet具有很多優(yōu)點(diǎn)高效率通過(guò)Servlet,Java虛擬機(jī)用輕量級(jí)的Java線程處理每個(gè)請(qǐng)求。同時(shí)有N個(gè)請(qǐng)求的情況下,CGI程序需要被調(diào)入到效勞器內(nèi)存N次;對(duì)于Servlet將開(kāi)啟N個(gè)線程,但僅僅調(diào)入一個(gè)Servlet實(shí)例到內(nèi)存中應(yīng)用方便Servlet在解析和譯碼HTML數(shù)據(jù),讀取設(shè)置HTML標(biāo)題,操作Cookie等很多方面,應(yīng)用更加方便。繼承自java的特點(diǎn),其可靠性與復(fù)用性好功能強(qiáng)大Servlet可以直接與Web效勞程序?qū)υ挘欢鄠€(gè)Servlet可以共享數(shù)據(jù);Servlet與數(shù)據(jù)庫(kù)的連接也比較簡(jiǎn)單等10.1Java網(wǎng)絡(luò)程序設(shè)計(jì)的根本概念10.1.5Servlet(續(xù))
——優(yōu)點(diǎn)23便攜性好Servlet用Java語(yǔ)言編寫,遵循標(biāo)準(zhǔn)的API。因此Servlet編寫的程序可以無(wú)任何修改的在Apache,MicrosoftInternetInformationServer(IIS),IBMWebSphere,或者StarNineWebStar上運(yùn)行。同樣具有一次編譯,到處運(yùn)行移植性好的特點(diǎn)平安基于Java語(yǔ)言的平安特性,Servlet的平安性也比較可靠本錢低有很多免費(fèi)或相比照較廉價(jià)的Web效勞器,適合做個(gè)人的或者小容量的網(wǎng)站。而且很多商業(yè)級(jí)的Web效勞器相對(duì)也比較廉價(jià)。而且使一個(gè)效勞器支持Servlet所需的額外花費(fèi)也很少10.1Java網(wǎng)絡(luò)程序設(shè)計(jì)的根本概念10.1.5Servlet(續(xù))
——優(yōu)點(diǎn)2410.2Servlet根底本節(jié)內(nèi)容包括Servlet容器、web效勞器、應(yīng)用效勞器Web應(yīng)用程序ServletAPIServlet的根本結(jié)構(gòu)Servlet編譯和安裝25Servlet容器也稱為Servlet引擎是一個(gè)編譯好的可執(zhí)行程序,它是web效勞器與servlet間的媒介負(fù)責(zé)將請(qǐng)求翻譯成Servlet能夠理解的形式傳遞給servlet,同時(shí)傳給servlet一個(gè)對(duì)象使之可以送回響應(yīng)負(fù)責(zé)管理servlet的生命周期10.2Servlet根底10.2.1Servlet容器、Web效勞器和應(yīng)用效勞器26web效勞器能夠處理Http請(qǐng)求的效勞器可以提供靜態(tài)頁(yè)面、圖像等有的web效勞器也支持動(dòng)態(tài)頁(yè)面的生成,支持JSP、Servlet等,具有JVM應(yīng)用效勞器可以處理基于多種協(xié)議的請(qǐng)求,當(dāng)然也包括Http協(xié)議可以支持servlets和JSP,以及所有其他J2EE效勞,包括JNDI、EJBs、JMS等10.2Servlet根底10.2.1Servlet容器、Web效勞器和應(yīng)用效勞器27servlet容器可以與web效勞器協(xié)作提供對(duì)servlet的支持一些servlet容器〔如ApacheTomcat〕自己也可以作為獨(dú)立的web效勞器運(yùn)行隨著servlet和JSP的流行,一些主要的Web效勞器和應(yīng)用程序效勞器都直接或者通過(guò)插件支持servlet和JSP。如:SunONEApplicationServerLotusDominoGoWebServerBEAweblogicTengahServerWebSphere應(yīng)用效勞器JigsawNetForgeAcmeServerMotBaysJetty10.2Servlet根底10.2.1Servlet容器、Web效勞器和應(yīng)用效勞器28ApacheTomcat5是servlet2.4和JSP2.0標(biāo)準(zhǔn)的官方參考實(shí)現(xiàn)完全免費(fèi),并且提供完整的源代碼可以到下載最新版本初始設(shè)置設(shè)置JAVA_HOME。假設(shè)JDK安裝在F:\ProgramFiles\Java\jdk1.6.0_10,可以仿照path和classpath的設(shè)置方法,新建一個(gè)環(huán)境變量:JAVA_HOME=F:\ProgramFiles\Java\jdk1.6.0_1010.2Servlet根底10.2.1Servlet容器、Web效勞器和應(yīng)用效勞器
——ApacheTomcat5效勞器及其初始設(shè)置29為方便調(diào)試,還可進(jìn)行如下設(shè)置啟動(dòng)servlet重新載入功能〔所請(qǐng)求servlet類文件發(fā)生變化后,自動(dòng)重新載入到效勞器內(nèi)存〕。翻開(kāi)install_dir/conf/server.xml,在注釋<!--Definepropertiesforeachwebapplication-->后插入語(yǔ)句<DefaultContextreloadable=“true”/>開(kāi)啟servlet調(diào)用器invokerservlet〔可以不修改Web應(yīng)用的web.xml文件即可運(yùn)行servlet〕。翻開(kāi)install_dir/conf/web.xml,將servlet-mapping元素取消注釋<servlet-mapping><servlet-name>invoker</servlet-name><url-pattern>/servlet/*</url-pattern></servlet-mapping>10.2Servlet根底10.2.1Servlet容器、Web效勞器和應(yīng)用效勞器
——ApacheTomcat5效勞器及其初始設(shè)置30在install_dir/conf/web.xml中,將以下元素取消注釋:
<servlet><servlet-name>invoker</servlet-name><servlet-class></servlet-class><init-param><param-name>debug</param-name>
<param-value>0</param-value></init-param>
<load-on-startup>2</load-on-startup></servlet>對(duì)于Tomcat6,還需在install_dir/conf/context.xml文件中,對(duì)Context節(jié)點(diǎn)添加“privileged="true"”屬性,如下:<Contextprivileged="true">…………</Context>10.2Servlet根底10.2.1Servlet容器、Web效勞器和應(yīng)用效勞器
——ApacheTomcat5效勞器及其初始設(shè)置3110.2.2Web應(yīng)用程序Web應(yīng)用程序組成局部包括servlet、JSP及其支持文件這些組成局部需要進(jìn)行部署通常部署在Tomcat的webapps子目錄中。一般其目錄結(jié)構(gòu)包括根目錄(contextroot)和幾個(gè)子目錄,也可以把子目錄捆綁到一個(gè)類型為war的存檔文件中10.2Servlet根底3210.2.2Web應(yīng)用程序(續(xù))webapps子目錄一般包括,WEB-INF包含Web應(yīng)用程序的部署描述文件(web.xml)在web.xml文件中配置Web應(yīng)用程序。可以制訂各種配置參數(shù):調(diào)用servlet的名稱、servlet的描述、servlet的完全的類名和servlet容器調(diào)用servlet的路徑修改web.xml的部署描述符后,需要重新啟動(dòng)Tomcat效勞器WEB-INF/classes包括Web應(yīng)用程序中所使用的servlet和實(shí)用工具類文件。如果類文件是包的組成局部,那么包的目錄結(jié)構(gòu)從該目錄開(kāi)始WEB-INF/lib包含Java存檔文件(JAR文件),是servlet和實(shí)用工具類文件10.2Servlet根底3310.2.3ServletAPIServletAPI開(kāi)發(fā)servlet和JSP程序,需要參考ServletAPI文檔包含javax.servlet和兩個(gè)包中所有servlet須實(shí)現(xiàn)接口,通常繼承如下兩個(gè)類中的一個(gè)GenericServletHttpServletServletGenericservletHttpservletMyservlet10.2Servlet根底34Servlet接口所有servlets必須實(shí)現(xiàn)這一接口Servlet接口的所有方法都是被自動(dòng)調(diào)用的HttpServlet類覆蓋了接口的service方法service方法由servlet容器調(diào)用,對(duì)客戶端的請(qǐng)求作出響應(yīng)。它會(huì)根據(jù)請(qǐng)求類型的不同自動(dòng)調(diào)用doGet或doPost等方法能夠處理兩個(gè)最普通的HTTP請(qǐng)求類型doGet方法響應(yīng)get請(qǐng)求doPost方法響應(yīng)post請(qǐng)求10.2.3ServletAPI(續(xù))10.2Servlet根底3510.2.3ServletAPI(續(xù))HttpServletRequest接口由Web效勞器創(chuàng)立該接口的一個(gè)對(duì)象,并將其傳遞給servlet的service方法該類對(duì)象含有來(lái)自于客戶端的請(qǐng)求HttpServletResponse接口由Web效勞器創(chuàng)立該接口的一個(gè)對(duì)象,并將其傳送給servlet的service方法通過(guò)該類對(duì)象效勞器端可以對(duì)客戶端發(fā)出響應(yīng)信息10.2Servlet根底3610.2.4Servlet的根本結(jié)構(gòu)Servlet的根本結(jié)構(gòu)一般擴(kuò)展自HttpServlet覆蓋doGet或者doPost方法doGet或doPost都接收兩個(gè)類型的參數(shù):HttpServletRequest和HttpServletResponse通過(guò)HttpServletRequest,可以得到所有的輸入數(shù)據(jù),比方表單數(shù)據(jù)、HTTP請(qǐng)求報(bào)頭等客戶信息通過(guò)HttpServletResponse可以指定輸出信息由于doGet和doPost方法可能生成異常,必須在方法名稱后聲明拋出異常或者用try-catch語(yǔ)句處理異常10.2Servlet根底37GET請(qǐng)求是WEB瀏覽器請(qǐng)求的常見(jiàn)類型,用來(lái)請(qǐng)求Web頁(yè)面。本例中通過(guò)doGet方法處理GET請(qǐng)求。在doGet方法中通過(guò)HttpServletResponse對(duì)象得到PrintWriter,然后將一個(gè)文檔發(fā)給客戶。最終在客戶端生成一個(gè)網(wǎng)頁(yè)importjava.io.*;importjavax.servlet.*;importjavax.servlet..*;publicclassMyServletextendsHttpServlet{ publicvoiddoGet(HttpServletRequestreq,HttpServletResponseres)throwsServletException,IOException{res.setContentType("text/html"); PrintWriterout=res.getWriter(); out.println("<HTML>"); out.println("<HEAD><TITLE>MyFirstServlet</TITLE></HEAD>"); out.println("<BODY>"); out.println("<B>FirstServlet</B>"); out.println("</BODY></HTML>"); }}10.2.4Servlet的根本結(jié)構(gòu)(續(xù))
——例10-210.2Servlet根底3810.2.5Servlet編譯和安裝編譯——在設(shè)置好path和classpath的前提下,servlet的編譯和普通的java程序完全相同可以通過(guò)javac.exe編譯,比方可以在Dos環(huán)境下輸入:javacMyServlet.java也可以通過(guò)集成開(kāi)發(fā)環(huán)境(IDE)編譯復(fù)制——編譯成功之后,將生成的類文件復(fù)制到相應(yīng)的目錄下即可。在Tomcat效勞器上,此目錄可能是install_dir\webapps\ROOT\WEB-INF\classes\運(yùn)行——啟動(dòng)Tomcat效勞器,在地址欄輸入://localhost:8080/servlet/MyServlet10.2Servlet根底3910.3Servlet的生命周期首先效勞器僅創(chuàng)立servlet的一個(gè)實(shí)例創(chuàng)立servlet實(shí)例時(shí),它的init方法都會(huì)被調(diào)用針對(duì)每個(gè)客戶端的每個(gè)請(qǐng)求,都會(huì)創(chuàng)立一個(gè)線程該線程調(diào)用servlet實(shí)例的service方法Service方法根據(jù)收到HTTP請(qǐng)求得類型,調(diào)用doGet,doPost或者其他方法多個(gè)并發(fā)請(qǐng)求,一般會(huì)導(dǎo)致多個(gè)線程同時(shí)調(diào)用service方法,通過(guò)單線程模式〔SingleThreadModel〕也可以規(guī)定任何時(shí)間僅允許一個(gè)線程運(yùn)行最后,卸載servlet效勞器調(diào)用servlet的destroy方法4010.3Servlet的生命周期(續(xù))
——Servlet生命周期示意圖4110.3.1初始化servlet的初始化效勞器啟動(dòng),servlet被用戶首次調(diào)用,效勞器構(gòu)造servlet實(shí)例之后,即立刻調(diào)用init(ServletConfig)方法,執(zhí)行servlet實(shí)例的初始化工作ServeletConfig對(duì)象包含servlet初始化所需的很多參數(shù),比方計(jì)數(shù)器、默認(rèn)值等init方法都會(huì)在servlet處理客戶請(qǐng)求(request)之前被調(diào)用一旦init方法被調(diào)用,只有效勞器通過(guò)destroy方法銷毀servlet之后,init方法才能再次被調(diào)用10.3Servlet的生命周期4210.3.1初始化(續(xù))init方法的定義publicvoidinit(ServletConfigconfig)throwsServletException{ super.init(config); Stringgreeting=getInitParameter("greeting"); //Initializationcode…}10.3Servlet的生命周期4310.3.2銷毀servlet的銷毀效勞器卸載servlet實(shí)例之前,需要先調(diào)用servlet的destroy方法釋放servlet所獲得的資源使servlet有時(shí)機(jī)關(guān)閉數(shù)據(jù)庫(kù)連接、停止后臺(tái)運(yùn)行的線程、將cookie列表和點(diǎn)擊數(shù)寫入到磁盤執(zhí)行其他清理活動(dòng)10.3Servlet的生命周期4410.4與客戶端交互HTTPservlet與客戶端的交互通過(guò)service方法處理客戶端的請(qǐng)求service方法根據(jù)請(qǐng)求(request)類型的不同,調(diào)用不同的方法對(duì)于GET請(qǐng)求,調(diào)用doGet()方法進(jìn)行處理對(duì)于POST請(qǐng)求,調(diào)用doPost()方法進(jìn)行處理4510.4.1提取Servlet信息注冊(cè)的servlet都有相關(guān)的很多初始化參數(shù)這些初始化參數(shù)寫在web.xml中。getInitParameter()方法可以得到servlet初始化的一些參數(shù)返回一個(gè)指定參數(shù)的值〔String類型〕如果指定參數(shù)不存在,那么返回nullgetInitParameterNames()方法可以得到初始化參數(shù)名稱返回String類型的Enumeration類型數(shù)據(jù)如果不存在初始化參數(shù),那么返回一個(gè)null的Enumeration10.4與客戶端交互46通過(guò)servlet初始化參數(shù)建立一個(gè)數(shù)據(jù)庫(kù)連接的程序段如下java.sql.Connectioncon=null;publicvoidinit(ServletConfigconfig)throwsServletException{ super.init(config); Stringhost=getInitParameter("host");
intport=Integer.parseInt(getInitParameter("port"));
Stringdb=getInitParameter("db"); Stringuser=getInitParameter("user"); Stringpassword=getInitParameter("password"); Stringproxy=getInitParameter("proxy");
con=establishConnection(host,port,db,user,password,proxy);}10.4與客戶端交互10.4.1提取Servlet信息(續(xù))
——通過(guò)初始化建立數(shù)據(jù)庫(kù)連接47輸出全部初始化參數(shù)名稱importjava.io.*;importjava.util.*;importjavax.servlet.*;publicclassPrintInitParaNamesextendsGenericServlet{ publicvoidservice(ServletRequestreq,ServletResponseres) throwsServletException,IOException{
res.setContentType("text/plain"); PrintWriterout=res.getWriter(); out.println("InitParametersAsFollowing:"); Enumerationenum=getInitParameterNames(); while(enum.hasMoreElements()){ Stringname=(String)enum.nextElement(); out.println(name":"+getInitParameter(name)); }}}10.4與客戶端交互10.4.1提取Servlet信息(續(xù))
——PrintInitParaNames.java4810.4.2提取效勞器信息servlet可以得到很多效勞器相關(guān)的信息,同時(shí)可以將這些信息發(fā)送到客戶端getServerName()返回效勞器名稱getServerPort()返回效勞器監(jiān)聽(tīng)端口getServerInfo()輸出效勞器程序和版本,之間用“/”分開(kāi)getAttribute()返回效勞程序的屬性得到路徑相關(guān)的信息publicStringHttpServletRequest.getPathInfo()publicStringHttpServletRequest.getPathTranslated()10.4與客戶端交互49提取效勞器信息舉例importjava.io.*;importjava.util.*;importjavax.servlet.*;publicclassServerSnoopextendsGenericServlet{publicvoidservice(ServletRequestreq,ServletResponseres)throwsServletException,IOException{res.setContentType("text/plain");PrintWriterout=res.getWriter();out.println("req.getServerName()output:"+req.getServerName());out.println("req.getServerPort()output:"+req.getServerPort());out.println("getServletContext().getServerInfo()output:" +getServletContext().getServerInfo());out.println("getServletContext().getAttribute(\"attribute\")output:"+getServletContext().getAttribute("attribute"));}}10.4與客戶端交互10.4.2提取效勞器信息(續(xù))
——例10-35010.4.3提取客戶端信息效勞器可以從request得到很多客戶端的信息getRemoteAddr():得到IP地址getRemoteHost():得到客戶端機(jī)器的名稱利用InetAddress.getByName()方法可以將IP地址或客戶端機(jī)器名稱轉(zhuǎn)換成一個(gè)類型的對(duì)象InetAddressremoteInetAddress=InetAddress.getByName(req.getRemoteAddr());通過(guò)獲取客戶端的地址,并判斷是否隸屬某個(gè)范圍,可以限制某個(gè)地區(qū)的用戶訪問(wèn)你的網(wǎng)站10.4與客戶端交互5110.4.3提取客戶端信息(續(xù))效勞器可以得到客戶想做的事情客戶請(qǐng)求表現(xiàn)為表單數(shù)據(jù),由“名/值”對(duì)組成。當(dāng)提交某一個(gè)網(wǎng)頁(yè)的時(shí)候常常在瀏覽器地址欄中看到類似格式的數(shù)據(jù)格式name/value,每對(duì)之間用&隔開(kāi),表達(dá)式為param1=value1¶m2=value2¶m3=value3…request.getParameter:得到表單參數(shù)的值request.getParameterValues:得到屢次出現(xiàn)的參數(shù)值reques.getParameterNames:得到當(dāng)前請(qǐng)求中所有參數(shù)的完整列表,調(diào)用形式如下publicStringServletRequest.getParameter(Stringname)publicString[]ServletRequest.getParameterValues(Stringname)10.4與客戶端交互52書本查詢的一個(gè)HTML網(wǎng)頁(yè)!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.01Transitional//EN"><HTML><HEAD><TITLE>ASampleFormforQueryaBook</TITLE></HEAD><BODYBGCOLOR="#FDF5E6"><FORMMETHOD=GETACTION="/Chapter11/QueryServlet">Booktolookup:<INPUTTYPE="TEXT"NAME="Book"VALUE="JavaServletProgramming"><!--Thedefaultbooktobelookedupis:《JavaServletProgramming》.--><INPUTTYPE=SUBMIT></FORM></BODY></HTML>10.4與客戶端交互10.4.3提取客戶端信息(續(xù))
——Query.html53獲取客戶端信息的servletimportjava.io.*;import.*;importjavax.servlet.*;importjavax.servlet..*;publicclassQueryServletextendsHttpServlet{publicvoiddoGet(HttpServletRequestreq,HttpServletResponseres) throwsServletException,IOException{res.setContentType("text/html;charset=UTF-8");StringqueryBookValue=req.getParameter("Book");PrintWriterout=res.getWriter();out.println("Thebookyouwantedis:"+queryBookValue);out.close();}}10.4與客戶端交互10.4.3提取客戶端信息(續(xù))
——QueryServlet.java5410.4與客戶端交互10.4.3提取客戶端信息(續(xù))
——Query.html與QueryServlet運(yùn)行結(jié)果5510.4.4發(fā)送HTML信息Web效勞器響應(yīng)(response)的構(gòu)成狀態(tài)行由版本(HTTP/1.1),一個(gè)狀態(tài)代碼(200)和一段對(duì)應(yīng)狀態(tài)代碼的簡(jiǎn)短消息(OK)組成一些響應(yīng)報(bào)頭、Content-Type:text/html指定后面文檔MIME類型,后面的其他報(bào)頭可選。常用MIME類型有:text/html:HTML文檔text/plain:純文本text/xml:XMLimage/jpeg:JEPG圖像application/msword:MicrosoftWord文檔application/pdf:crobat文件application/zip:Zip檔案一個(gè)空行和響應(yīng)的文檔10.4與客戶端交互56HTTP/1.1200OK //狀態(tài)行Content-Type:text/html //報(bào)頭Header2:……HeaderN:… //空行<!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.0Transitional//EN"> //文檔<HTML><HEAD>headcode</HEAD><BODY>…</BODY></HTML>10.4.4發(fā)送HTML信息(續(xù))10.4與客戶端交互57向客戶端輸出一個(gè)簡(jiǎn)單網(wǎng)頁(yè),顯示“HelloWorld!”importjava.io.*;importjavax.servlet.*;importjavax.servlet..*;publicclassHelloWorldextendsHttpServlet{publicvoiddoGet(HttpServletRequestreq,HttpServletResponseres)throwsServletException,IOException{res.setContentType("text/html");PrintWriterout=res.getWriter();out.println("<HTML>");out.println("<HEAD><TITLE>HelloWorld</TITLE></HEAD>");out.println("<BODY>");out.println("<BIG>HelloWorld!</BIG>");out.println("</BODY></HTML>");}}10.4與客戶端交互10.4.4發(fā)送HTML信息(續(xù))
——例10-458程序說(shuō)明HelloWorld繼承了HttpServlet,然后重寫doGet方法在doGet方法中,首先將HTTPContent-Type響應(yīng)報(bào)頭設(shè)置為text/html,即指定響應(yīng)的類型為HTML文檔;然后通過(guò)getWriter()得到PrintWriter類型的一個(gè)對(duì)象out,按照HTML格式輸出一個(gè)簡(jiǎn)單網(wǎng)頁(yè)運(yùn)行結(jié)果10.4與客戶端交互客戶端跟蹤10.4.4發(fā)送HTML信息(續(xù))
——例10-4運(yùn)行結(jié)果5910.5客戶端跟蹤客戶端跟蹤HTTP是無(wú)狀態(tài)協(xié)議,效勞器不能自動(dòng)維護(hù)客戶連接的上下文信息許多情況下,Web效勞器必須要能夠跟蹤用戶的狀態(tài)比方購(gòu)物網(wǎng)站和電子郵件網(wǎng)站,當(dāng)用戶登錄以后,其身份和一系列的操作狀態(tài)都需要被跟蹤并保持servletAPI提供了兩種可以跟蹤客戶端狀態(tài)的方法CookieSession6010.5.1使用CookieCookie是Web效勞器保存在用戶硬盤上的一段文本,Web效勞器將它發(fā)送到瀏覽器之后,當(dāng)再次訪問(wèn)同一網(wǎng)絡(luò)時(shí),瀏覽器將它原封不動(dòng)的返回其中的信息片斷以‘名/值’對(duì)(name-valuepairs)的形式儲(chǔ)存使用這種方法,網(wǎng)站可以維護(hù)客戶的連接。這種用途可以表達(dá)在如下幾點(diǎn)在電子商務(wù)中標(biāo)識(shí)用戶,實(shí)現(xiàn)短期跟蹤用戶記錄用戶名和用戶密碼,允許用戶下次自動(dòng)登陸定制站點(diǎn),記錄用戶的偏好定向廣告,記錄用戶感興趣的主題,并顯示與之相關(guān)的廣告10.5客戶端跟蹤61調(diào)用Cookie的構(gòu)造方法可創(chuàng)立一個(gè)cookie構(gòu)造方法接受兩個(gè)字符串參數(shù)cookie名稱cookie的值例如創(chuàng)立一個(gè)名為CookieName,值為John的cookie,可以使用下面的語(yǔ)句Cookielogin=newCookie(“CookieName”,”John”);10.5客戶端跟蹤10.5.1使用Cookie(續(xù))
——?jiǎng)?chuàng)立Cookie對(duì)象62創(chuàng)立了一個(gè)名為login的cookie之后,可通過(guò)很多現(xiàn)有的方法設(shè)置cookie的值和屬性可通過(guò)如下語(yǔ)句設(shè)置cookie的注釋:login.setComent(“YoucangetUserNameformthiscookie”);創(chuàng)立cookie并將它發(fā)送到瀏覽器后,默認(rèn)情況下,它是會(huì)話級(jí)的cookie,僅僅存儲(chǔ)在瀏覽器內(nèi)存中,用戶退出瀏覽器后,cookie將被刪除;如果希望將cookie存儲(chǔ)在磁盤上,那么需要設(shè)定MaxAge,給出一個(gè)以秒為單位的生命周期,如下可以將生命設(shè)置為一天login.setMaxAge(60*60*24) //onedaysetPath(),setValue(),setVersion(),setDomain(),setSecure()等,相關(guān)的具體用法請(qǐng)查看servletAPI10.5客戶端跟蹤10.5.1使用Cookie(續(xù))
——設(shè)置Cookie屬性63剛創(chuàng)立的cookie存在于效勞器內(nèi)存中。必須將它發(fā)送到客戶端,cookie才能真正的發(fā)揮作用。發(fā)送cookie需要使用HttpServletResponse的addCookie方法,將cookie插入到一個(gè)HTTP響應(yīng)報(bào)頭。發(fā)送的語(yǔ)句如下publicvoiddoGet(HttpServletRequestreq,HttpServletResponseres)throwsServletException,IOException{Cookielogin=newCookie(“UserName”,”John”);login.setComent(“YoucangetUserNameformthiscookie”);res.addCookie(login);//...}10.5客戶端跟蹤10.5.1使用Cookie(續(xù))
——發(fā)送Cookie到客戶端64從客戶端讀取你感興趣的cookie,需要兩個(gè)步驟首先調(diào)用request.getCookies得到一個(gè)Cookie對(duì)象的數(shù)組然后調(diào)用每個(gè)cookie的getName方法,從數(shù)組中尋找所需的cookieStringnameString=“UserName”Cookie[]cookies=request.getCookies();for(inti=0;i<cookies.length;i++){ Cookiecookie=cookies[i]; if(nameString.equals(cookie.getName())) { //dosomething…//cookies.setMaxAge(0); }}找到感興趣的cookie之后,便可以操作此cookie,如通過(guò)getValue方法得到相關(guān)cookie的值,設(shè)置MaxAge等10.5客戶端跟蹤10.5.1使用Cookie(續(xù))
——從客戶端讀取Cookie6510.5.2使用SessionSession一段時(shí)間內(nèi),單個(gè)客戶與web效勞器的一連串的交互過(guò)程在一個(gè)Session中客戶可能會(huì)屢次請(qǐng)求訪問(wèn)同一個(gè)網(wǎng)頁(yè),也有可能請(qǐng)求訪問(wèn)各種不同的效勞器資源,其間用戶的狀態(tài)需要跟蹤并保持存在于效勞器端,不在網(wǎng)絡(luò)上傳送它的好處是可以用來(lái)記錄客戶端私有的信息,并且在時(shí)間范圍內(nèi)不會(huì)消失10.5客戶端跟蹤6610.5.2使用Session(續(xù))Session的使用可以分為三個(gè)步驟獲得一個(gè)session存儲(chǔ)數(shù)據(jù)到session或從session讀取數(shù)據(jù)銷毀session10.5客戶端跟蹤67通過(guò)調(diào)用ServletRequest的getSession方法可以得到一個(gè)sessionHttpSessionsession=request.getSession();為了保持正確的會(huì)話,必須在發(fā)送任何文檔到客戶程序之前獲得一個(gè)sessionpublicclassSessionServletextendsHttpServlet{publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{//Gettheuser'ssessionHttpSessionsession=request.getSession(true);//...out=response.getWriter();//...}}10.5客戶端跟蹤10.5.2使用Session(續(xù))
——獲得一個(gè)Session68SessionIDServlet容器為HttpSession分配的一個(gè)唯一標(biāo)識(shí)符作為Cookie保存在客戶的瀏覽器中sessioncookie每次客戶發(fā)出HTTP請(qǐng)求時(shí),Servlet容器可以從HttpRequest對(duì)象中讀取SessionID,然后根據(jù)SessionID在效勞器端找到相應(yīng)的HttpSession對(duì)象,從而獲取客戶的狀態(tài)信息,這樣的cookie叫做sessioncookie存儲(chǔ)于瀏覽器內(nèi)存中的,并不寫到硬盤上的針對(duì)某一次會(huì)話而言,會(huì)話結(jié)束也就隨著消失了10.5客戶端跟蹤10.5.2使用Session(續(xù))
——存儲(chǔ)或讀取數(shù)據(jù)69URL重寫瀏覽器不支持Cookie,或者將瀏覽器設(shè)置為不接受Cookie的情況,可通過(guò)URL重寫來(lái)實(shí)現(xiàn)會(huì)話管理向URL連接添加參數(shù),并把sessionID作為值包含在連接中。為servlet響應(yīng)局部的每個(gè)連接添加sessionID,可以使用一對(duì)方法response.encodeURL():使URL包含sessionIDresponse.encodeRedirectURL():使用重定向10.5客戶端跟蹤10.5.2使用Session(續(xù))
——存儲(chǔ)或讀取數(shù)據(jù)70從Session中讀取數(shù)據(jù)session.getAttribute(“name”)查找以前存儲(chǔ)的值如果不存在那么返回null在調(diào)用此方法返回的對(duì)象前,一定要檢查它是否為null向session中設(shè)置相關(guān)信息setAttribute替換掉此前設(shè)定的任何值removeAttribute移除而不是替換某個(gè)值10.5客戶端跟蹤10.5.2使用Session(續(xù))
——存儲(chǔ)或讀取數(shù)據(jù)71publicclassSessionServletextendsHttpServlet{publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{ //Gettheuser'ssessionHttpSessionsession=request.getSession(true);SomeClassscl=(SomeClass)session.getAttribute("name1“);//IftheuserhasnoSomeClassobject,createanewoneif(scl==null){scl=newSomeClass();
session.putAttribute("name1",scl);}//...}}10.5客戶端跟蹤10.5.2使用Session(續(xù))
——SessionServlet.java72銷毀Session意味著從系統(tǒng)刪除session對(duì)象及其值自動(dòng)銷毀在一段時(shí)間〔時(shí)間長(zhǎng)短依賴與Web效勞器的設(shè)定〕沒(méi)有request的情況下,Web效勞器會(huì)自動(dòng)銷毀session手動(dòng)銷毀通過(guò)調(diào)用session的invalidate方法可以手動(dòng)的銷毀sessionlogout在支持servlet2.4的效勞器中,可調(diào)用logout將客戶從Web效勞器中注銷,同時(shí)廢棄所有與該用戶相關(guān)聯(lián)的會(huì)話需要注意的是,這個(gè)動(dòng)作會(huì)影響到此servlet之外的其他servlet,因此一定要與網(wǎng)站的其他開(kāi)發(fā)人員協(xié)調(diào)使用10.5客戶端跟蹤10.5.2使用Session(續(xù))
——銷毀Session7310.6協(xié)作與通信協(xié)作與通信為了更好的響應(yīng)客戶端的請(qǐng)求,servlet有時(shí)需要和網(wǎng)絡(luò)上的其他資源進(jìn)行通訊,比方HTML網(wǎng)頁(yè)其他servletJSP網(wǎng)頁(yè)Servlet協(xié)作通訊的第一步是獲得分發(fā)器(dispatcher),即RequestDispatcher接口的一個(gè)對(duì)象74RequestDispatcher接口產(chǎn)生一個(gè)RequestDispatcher接口的對(duì)象RequestDispatcherdispatcher=getServletContext().getRequestDispatcher("/SomePath/SomeString");通過(guò)設(shè)置字符串參數(shù),可以獲得servlet,HTML網(wǎng)頁(yè),JSP網(wǎng)頁(yè)等“資源”forward方法將本servlet的request請(qǐng)求傳遞給“其他資源”響應(yīng)通過(guò)利用此方法可實(shí)現(xiàn):servlet先預(yù)處理request,然后將處理后的request傳遞給“其他資源”處理include方法引入“其他資源”來(lái)響應(yīng)客戶端的請(qǐng)求10.6協(xié)作與通信(續(xù))
——RequestDispatcher接口75MyServlet1獲取另外一個(gè)servlet〔MyServlet2〕,并用它來(lái)響應(yīng)用戶的請(qǐng)求importjava.io.*;importjavax.servlet.*;importjavax.servlet..*;publicclassMyServlet1extendsHttpServlet{publicvoiddoGet(HttpServletRequestreq,HttpServletResponseres)throwsServletException,IOException{res.setContentType("text/html");RequestDispatchersummary=getServletContext().getRequestDispatcher("/servlet/MyServlet2");
10.6協(xié)作與通信(續(xù))
——MyServlet1.java76if(summary!=null){ try{summary.include(req,res); } catch(IOExceptione){}catch(ServletExceptione){} } elseif(summary==null){ PrintWriterout=res.getWriter(); out.println("<HTML>"); out.println("<HEAD><TITLE>Error</TITLE></HEAD>"); out.println("<BODY>"); out.println("<BIG>SummaryisNull</BIG>"); out.println("</BODY></HTML>");}}}10.6協(xié)作與通信(續(xù))
——MyServlet1.java77importjava.io.*;importjavax.servlet.*;importjavax.servlet..*;publicclassMyServlet2extendsHttpServlet{publicvoiddoGet(HttpServletRequestreq,HttpServletResponseres)throwsServletException,IOException{res.setContentType("text/html");PrintWriterout=res.getWriter();out.println("<HTML>");out.println("<HEAD><TITLE>MYsecondServlet</TITLE></HEAD>");out.println("<BODY>");out.println("<tableborder=2><tr><td>name</td><td>Bush</td>");out.println("<td>Sex</td><td>Male</td></tr><tr><td>City</td>");out.println("<td>NewYork</td><td>Country</td><td>U.S.A</td></tr>");out.println("</BODY><HTML>");}}10.6協(xié)作與通信(續(xù))
——MyServlet2.java10.6協(xié)作與通信(續(xù))
——MyServlet2.java78在IE地址欄輸入:://localhost:8084/Chapter11/MyServlet1,結(jié)果如下:7910.6.1Applet與Servlet的通信Applet與Servlet的通訊用戶用Applet發(fā)送消息到效勞器對(duì)于動(dòng)態(tài)網(wǎng)頁(yè),Applet與Servlet的通訊尤為重要比方在一個(gè)聊天系統(tǒng)中,當(dāng)一個(gè)用戶輸入了某些語(yǔ)句時(shí),聊天室內(nèi)的所有其他用戶都可以看到。此功能可能的實(shí)現(xiàn)步驟是用戶先把消息發(fā)給效勞器然后效勞器發(fā)送給聊天室內(nèi)的所有用戶Applet和Servlet通訊的方式有多種通過(guò)socket直接建立網(wǎng)絡(luò)連接通過(guò)遠(yuǎn)程方法調(diào)用(RemoteMethodInovation)通訊通過(guò)CORBA通訊10.6協(xié)作與通信80Socket通訊效勞器端的操作首先創(chuàng)立一個(gè)ServerSocket對(duì)象,在指定端口監(jiān)聽(tīng)客戶端的request在接收到request后,accept()方法返回一個(gè)Socket對(duì)象通過(guò)socket對(duì)象創(chuàng)立輸入輸出流對(duì)象,并實(shí)現(xiàn)與客戶端的交互交互完畢后,關(guān)閉輸入輸出流和socket,最后關(guān)閉ServerSocker客戶端的操作首先創(chuàng)立socket對(duì)象,建立與效勞器的連接然后通過(guò)socket對(duì)象創(chuàng)立輸入輸出流,實(shí)現(xiàn)與效勞器的交互最后關(guān)閉輸入輸出流和socket10.6協(xié)作與通信10.6.1Applet與Servlet的通信(續(xù))
——Socket通訊81RMI通訊RemoteMethodInvocation的簡(jiǎn)寫,即遠(yuǎn)程方法調(diào)用通過(guò)存在于遠(yuǎn)程機(jī)器上的對(duì)象,可以發(fā)消息給遠(yuǎn)程的機(jī)器,且可以取得遠(yuǎn)程機(jī)器程序執(zhí)行的結(jié)果。整個(gè)調(diào)用過(guò)程類似于此對(duì)象存在于本地機(jī)器,無(wú)疑這大大簡(jiǎn)化了通訊過(guò)程當(dāng)大量的數(shù)據(jù)是由效勞器端的對(duì)象動(dòng)態(tài)提供時(shí)使用RMI通訊是非常適宜的如何使用RMI先定義一個(gè)繼承自的公用接口。在該接口中定義要求在效勞器上運(yùn)行的方法接下來(lái)是實(shí)現(xiàn)遠(yuǎn)程接口,遠(yuǎn)程接口的實(shí)現(xiàn)類應(yīng)該實(shí)現(xiàn):定義遠(yuǎn)程對(duì)象的構(gòu)造方法,創(chuàng)立和安裝平安管理器,創(chuàng)立一個(gè)或多個(gè)遠(yuǎn)程對(duì)象實(shí)例,并注冊(cè)至少一個(gè)遠(yuǎn)程對(duì)象10.6協(xié)作與通信10.6.1Applet與Servlet的通信(續(xù))
——RMI通訊82通過(guò)CORBA通訊即公用對(duì)象請(qǐng)求代理體系〔CommonObjectRequestBrokerArchitecture〕,是OMA定義的一套和語(yǔ)言無(wú)關(guān)的分布式對(duì)象交換標(biāo)準(zhǔn)框架(Standardframeworkofobjectinteroperability)CORBA的主要功能是RPC(RemoteProcedureCall)式的支持,它使得本機(jī)對(duì)象可以調(diào)用遠(yuǎn)端對(duì)象的方法使用方法類似于RMI定義接口創(chuàng)立類實(shí)現(xiàn)接口在效勞器上注冊(cè)后客戶就可以像本地對(duì)象一樣訪問(wèn)遠(yuǎn)程對(duì)象了10.6協(xié)作與通信10.6
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- Taylor-Couette混凝實(shí)驗(yàn)絮凝劑殘留鋁的影響因素研究
- 黑龍江省農(nóng)業(yè)農(nóng)村現(xiàn)代化水平評(píng)價(jià)及優(yōu)化路徑研究
- miR-21-5p通過(guò)影響TAMs在肺癌進(jìn)展中的作用及機(jī)制研究
- 我長(zhǎng)大了-健康活動(dòng)
- 腹瀉的護(hù)理要點(diǎn)
- 小孩子機(jī)器人教育培訓(xùn)
- 工廠質(zhì)量培訓(xùn)課件
- 預(yù)防詐騙主題班會(huì)課件
- 預(yù)防地震知識(shí)培訓(xùn)課件
- 火災(zāi)預(yù)防知識(shí)培訓(xùn)
- 酒店衛(wèi)生管理自查報(bào)告和整改措施
- 安全教育培訓(xùn):實(shí)現(xiàn)安全文明施工
- 2025至2030分布式能源行業(yè)市場(chǎng)深度調(diào)研及發(fā)展規(guī)劃及有效策略與實(shí)施路徑評(píng)估報(bào)告
- 班主任常規(guī)工作培訓(xùn)課件
- 反邪教宣講課件
- 2025年全國(guó)統(tǒng)一高考英語(yǔ)Ⅰ卷(含答案)
- 1 感受生活中的法律 課件-道德與法治六年級(jí)上冊(cè)統(tǒng)編版
- 股份代持及員工持股計(jì)劃協(xié)議書范本
- 中醫(yī)集市活動(dòng)方案
- 2025年江蘇省南京市中考?xì)v史試卷(含解析)
- 腫瘤隨訪登記培訓(xùn)
評(píng)論
0/150
提交評(píng)論