版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1第十講Servlet程序設計鄭莉2目錄10.1Java網(wǎng)絡程序設計的根本概念——看MOOC:Java程序設計進階第四~五章10.2Servlet根底10.3Servlet的生命周期10.4與客戶端交互10.5客戶端跟蹤10.6協(xié)作與通訊10.7程序舉例10.8本章小結(jié)34網(wǎng)絡將世界聯(lián)系在一起,使世界變得更加豐富多彩。同時網(wǎng)絡互連是一個內(nèi)容豐富而復雜的主題,所以這方面的程序設計涉及面很廣且不易掌握與其他語言相比,Java語言在網(wǎng)絡應用程序方面具有一定的優(yōu)勢。Java提供了很多內(nèi)置的網(wǎng)絡功能,使得基于Internet和Web的應用開發(fā)變得更加容易10.1Java網(wǎng)絡程序設計的根本概念510.1.1協(xié)議所有使用或?qū)崿F(xiàn)某種Internet效勞的程序都必須遵從一個或多個網(wǎng)絡協(xié)議,這種協(xié)議很多,而IP、TCP、UDP是最為根本的三種協(xié)議,是所有其它協(xié)議的根底IP〔InternetProtocol,Internet協(xié)議〕是最底層的協(xié)議定義了數(shù)據(jù)按照數(shù)據(jù)報〔Datagram,一種自帶尋址信息的、獨立地從數(shù)據(jù)源走到終點的數(shù)據(jù)包〕傳輸?shù)母袷胶鸵?guī)那么TCP〔TransportControlProtocol,傳輸控制協(xié)議〕建立在IP之上,定義了網(wǎng)絡上程序到程序的數(shù)據(jù)傳輸格式和規(guī)那么,提供了IP數(shù)據(jù)包的傳輸確認、喪失數(shù)據(jù)包的重新請求、將收到的數(shù)據(jù)包按照它們的發(fā)送次序重新裝配的機制是面向連接的協(xié)議,在開始數(shù)據(jù)傳輸之前,必須先建立明確的連接UDP〔UserDatagramProtocol,用戶數(shù)據(jù)報協(xié)議〕與TCP相似,比TCP具有更好的傳輸效率。不可靠的,不保證數(shù)據(jù)的傳輸,也不提供重新排列次序或重新請求功能,是一種無連接協(xié)議10.1Java網(wǎng)絡程序設計的根本概念6HTTP協(xié)議〔HyperTextTransferProtocol〕是Internet眾多協(xié)議中的一種,表示超文本傳輸協(xié)議,它構(gòu)成了WWW的根底具有簡單快速、靈活、無狀態(tài)、無連接等特點基于請求〔Request〕/響應〔Response〕模式。其工作過程如下首先客戶端與效勞器建立連接然后客戶端發(fā)送一個請求給效勞器效勞器接到請求后,給予相應的響應信息;最后關(guān)閉連接,完成一次操作10.1.1協(xié)議(續(xù))
——HTTP協(xié)議10.1Java網(wǎng)絡程序設計的根本概念7客戶端發(fā)送給效勞器的請求有很多類型,被稱為方法,其中最常用的是GET、POSTGET方法用來從效勞器讀取信息,比方從效勞器讀取文件、表格、數(shù)據(jù)庫查詢結(jié)果等POST方法用來向效勞器傳送信息,比方把信用卡號、表格、存儲于數(shù)據(jù)庫的數(shù)據(jù)等傳送到效勞器HEAD方法用來讀取效勞器響應頭〔ResponseHead〕;得到諸如文件大小,文件最后修改時間,效勞器類型等信息PUT方法將文件直接傳到效勞器DELETE方法將文件直接從效勞器刪除TRACE方法用來協(xié)助程序調(diào)試OPTIONS方法用來查詢效勞器所支持的方法10.1Java網(wǎng)絡程序設計的根本概念10.1.1協(xié)議(續(xù))
——HTTP協(xié)議中客戶端發(fā)送給效勞器的請求810.1.2關(guān)于URIURI〔UniformResourceIdentifier,統(tǒng)一資源標識符〕HTTP協(xié)議用URI標識定位網(wǎng)絡上的數(shù)據(jù)如果知道了公布在網(wǎng)絡上的某個HTML文件的URI,不管文件位于什么地方,都可以通過HTTP訪問該文檔通常所說的URL是URI的一種10.1Java網(wǎng)絡程序設計的根本概念9URL類Java語言提供了URL類讓我們能在源代碼層使用URL有六個構(gòu)造方法,其中最簡單的是URL(Stringurl)。每個URL對象都封裝了資源的標識符和協(xié)議處理程序,可以調(diào)用URL的方法來提取URL的組件把URL對象作為AppletContext接口的showDocument方法的參數(shù),就可以使執(zhí)行applet的瀏覽器顯示URL所指定的資源10.1.2關(guān)于URI(續(xù))
——URL類10.1Java網(wǎng)絡程序設計的根本概念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)絡程序設計的根本概念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)絡程序設計的根本概念10.1.2關(guān)于URI(續(xù))
——例10-11210.1.3基于套接字的有連接通信基于套接字(socket)的有連接通信使用TCP協(xié)議一個socket必須在發(fā)送數(shù)據(jù)之前與目的地的socket取得連接一旦連接建立了,sockets就可以使用一個流接口完成翻開-讀-寫-關(guān)閉,所有的發(fā)送的信息都會在另一端以同樣的順序被接收面向連接的操作比無連接的操作效率低,但是數(shù)據(jù)的平安性高10.1Java網(wǎng)絡程序設計的根本概念13用Java建立簡單的效勞器程序需要五個步驟Step1:創(chuàng)立ServerSocket對象ServerSocketmyServer=newServerSocket(intport,intbacklog);Port指定一個可用的端口號,用來定位效勞器上的效勞器應用程序backlog指定能夠連接到效勞器的最多客戶數(shù)。連接客戶到達由backlog指定的最大客戶數(shù)量時,效勞器將拒絕客戶連接Step2:通過ServerSocket的accept方法監(jiān)聽客戶連接,效勞器無限期的監(jiān)聽客戶連接Socketconnection=myServer.accept();有一個客戶連接時,將產(chǎn)生并返回一個socket10.1Java網(wǎng)絡程序設計的根本概念10.1.3基于套接字的有連接通信(續(xù))
——效勞器端14Step3:通過Socket的方法getInputStream和getOutputStream獲取InputStream和OutputStream對象;通常將其他流類型和它們聯(lián)系起來,如:ObjectInputStreaminput=newObjectInputStream(connection.getInputStream());ObjectOutputStreamoutput=newObjectOutputStream(connection.getOutputStream());Step4:客戶和效勞器通過OutputStream和InputStream對象進行通信Step5:通信傳輸完畢,效勞器通過調(diào)用流和套接字的close方法關(guān)閉連接10.1Java網(wǎng)絡程序設計的根本概念10.1.3基于套接字的有連接通信(續(xù))
——效勞器端15在客戶端建立簡單連接的思路類似,可分為四步Step1:建立一個Socket,實現(xiàn)與效勞器的連接Socketconnection=newSocket(InetAddressaddress,intport);address:效勞器IP地址。port:端口號連接成功,將返回一個Socket,否那么產(chǎn)生異常Step2:通過getInputStream和getOutputStream分別獲取Socket的InputStream和OutputStream的引用。同樣,也可以將其他流類型與InputStream和OutputStream聯(lián)系起來Step3:客戶與效勞器通過InputStream和OutputStream進行通信Step4:傳輸完畢后,通過調(diào)用流和套接字的close方法關(guān)閉連接10.1Java網(wǎng)絡程序設計的根本概念10.1.3基于套接字的有連接通信(續(xù))
——客戶端16數(shù)據(jù)報通信(DatagramCommunication)使用用戶數(shù)據(jù)報協(xié)議(UserDatagramProtocol,UDP)與TCP不同的一種協(xié)議不能保證數(shù)據(jù)會被成功地送達,也不保證數(shù)據(jù)抵達的次序與送出的次序相同,所以也被稱為“不可靠的通信協(xié)議”,雖然可靠性不高,但是它的速度很快,所以有些場合也有很大的用處效勞器通過DatagramSocket接收或發(fā)送信息,這些信息以DatagramPackets的形式存在DatagramSocketmySocket=newDatagramSocket(intport);port表示端口,上述語句將效勞器綁定到一個可以從客戶端接收packet的端口上,如果綁定失敗,將產(chǎn)生SocketException異常10.1Java網(wǎng)絡程序設計的根本概念10.1.4數(shù)據(jù)報通信17客戶端應用程序的工作流程Step1:通過創(chuàng)立一個DatagramSocket對象來建立數(shù)據(jù)報通訊的Socket。有如下兩種構(gòu)造方法publicDatagramSocket()構(gòu)造一個數(shù)據(jù)報socket,并使其與本地主機任一可用的端口連接。假設打不開socket那么拋出SocketException異常。publicDatagramSocket(intport)構(gòu)造一個數(shù)據(jù)報socket,并使其與本地主機指定的端口連接。假設打不開socket或socket無法與指定的端口連接那么拋出SocketException異常10.1Java網(wǎng)絡程序設計的根本概念10.1.4數(shù)據(jù)報通信(續(xù))
——客戶端18Step2:用DatagramPacket類來創(chuàng)立一個數(shù)據(jù)報包,用來實現(xiàn)無連接的包傳送效勞DatagramPacket對象封裝了數(shù)據(jù)報包的數(shù)據(jù)(bufferedarray[],包長度(length),目標地址(address),目標端口(port);length必須小于等于bufferedarry.lengthDatagramPacket〔bytebufferedarray[],intlength,InetAddressaddress,intport〕DatagramPacket類提供了四個方法來獲取信息publicbyte[]getData()返回一個字節(jié)數(shù)組,包含收到或要發(fā)送的數(shù)據(jù)報中的數(shù)據(jù)publicintgetLength()返回發(fā)送或接收到的數(shù)據(jù)的長度publicInetAddressgetAddress()返回一個發(fā)送或接收此數(shù)據(jù)報包文的機器的IP地址publicintgetPort()返回發(fā)送或接收數(shù)據(jù)報的遠程主機的端口號10.1Java網(wǎng)絡程序設計的根本概念10.1.4數(shù)據(jù)報通信(續(xù))
——客戶端19Step3:調(diào)用DatagramSocket對象的send(DatagramPacketp)方法發(fā)送數(shù)據(jù)報文包Step4:調(diào)用DatagramSocket對象的receive(DatagramPacketp)方法接收從效勞器返回的結(jié)果數(shù)據(jù)報文包該DatagramPacket對象用到另一種構(gòu)造方法,只需指明存放接收的數(shù)據(jù)報的緩沖區(qū)和長度DatagramPacket〔bytebufferedarray[],intlength〕receive方法會一直阻塞,直到收到一個數(shù)據(jù)報文包,此時DatagramPacket的緩沖區(qū)中包含的就是接收到的數(shù)據(jù),也包含發(fā)送者的IP地址,發(fā)送者機器上的端口號等信息Step5:處理接收緩沖區(qū)內(nèi)的數(shù)據(jù),獲取效勞結(jié)果Step6:通訊完成后,使用DatagramSocket對象的close()方法來關(guān)閉數(shù)據(jù)報通訊Socket10.1Java網(wǎng)絡程序設計的根本概念10.1.4數(shù)據(jù)報通信(續(xù))
——客戶端20效勞器端應用程序的工作流程與客戶端應用程序的通訊過程非常相似建立數(shù)據(jù)報通訊DatagramSocket構(gòu)建數(shù)據(jù)報文包DatagramPacket接收數(shù)據(jù)報和發(fā)送數(shù)據(jù)報,處理接收緩沖區(qū)內(nèi)的數(shù)據(jù)通訊完畢后,關(guān)閉數(shù)據(jù)報通訊Socket不同的是,效勞器應用程序要面向網(wǎng)絡中的所有計算機,所以效勞器應用程序收到一個包文后要分析它,得到數(shù)據(jù)報的源地址信息,這樣才能創(chuàng)立正確的返回結(jié)果報文給客戶機10.1Java網(wǎng)絡程序設計的根本概念10.1.4數(shù)據(jù)報通信(續(xù))
——效勞器端2110.1.5ServletServlet是用java技術(shù)來實現(xiàn)CGI〔CommonGatewayInterface,通用網(wǎng)關(guān)接口〕功能的編程介于瀏覽器〔或其他HTTP客戶端〕與效勞器之間,起到橋梁的作用。具體作用為:讀取客戶端發(fā)送的數(shù)據(jù)獲取客戶請求〔request〕中所包含的信息產(chǎn)生響應結(jié)果,并將結(jié)果包含到一個文件中,比方HTML文件中設置HTTP響應參數(shù),比方告訴瀏覽器,文件類型為HTML將文件返回給客戶端10.1Java網(wǎng)絡程序設計的根本概念22Servlet具有很多優(yōu)點高效率通過Servlet,Java虛擬機用輕量級的Java線程處理每個請求。同時有N個請求的情況下,CGI程序需要被調(diào)入到效勞器內(nèi)存N次;對于Servlet將開啟N個線程,但僅僅調(diào)入一個Servlet實例到內(nèi)存中應用方便Servlet在解析和譯碼HTML數(shù)據(jù),讀取設置HTML標題,操作Cookie等很多方面,應用更加方便。繼承自java的特點,其可靠性與復用性好功能強大Servlet可以直接與Web效勞程序?qū)υ?;多個Servlet可以共享數(shù)據(jù);Servlet與數(shù)據(jù)庫的連接也比較簡單等10.1Java網(wǎng)絡程序設計的根本概念10.1.5Servlet(續(xù))
——優(yōu)點23便攜性好Servlet用Java語言編寫,遵循標準的API。因此Servlet編寫的程序可以無任何修改的在Apache,MicrosoftInternetInformationServer(IIS),IBMWebSphere,或者StarNineWebStar上運行。同樣具有一次編譯,到處運行移植性好的特點平安基于Java語言的平安特性,Servlet的平安性也比較可靠本錢低有很多免費或相比照較廉價的Web效勞器,適合做個人的或者小容量的網(wǎng)站。而且很多商業(yè)級的Web效勞器相對也比較廉價。而且使一個效勞器支持Servlet所需的額外花費也很少10.1Java網(wǎng)絡程序設計的根本概念10.1.5Servlet(續(xù))
——優(yōu)點2410.2Servlet根底本節(jié)內(nèi)容包括Servlet容器、web效勞器、應用效勞器Web應用程序ServletAPIServlet的根本結(jié)構(gòu)Servlet編譯和安裝25Servlet容器也稱為Servlet引擎是一個編譯好的可執(zhí)行程序,它是web效勞器與servlet間的媒介負責將請求翻譯成Servlet能夠理解的形式傳遞給servlet,同時傳給servlet一個對象使之可以送回響應負責管理servlet的生命周期10.2Servlet根底10.2.1Servlet容器、Web效勞器和應用效勞器26web效勞器能夠處理Http請求的效勞器可以提供靜態(tài)頁面、圖像等有的web效勞器也支持動態(tài)頁面的生成,支持JSP、Servlet等,具有JVM應用效勞器可以處理基于多種協(xié)議的請求,當然也包括Http協(xié)議可以支持servlets和JSP,以及所有其他J2EE效勞,包括JNDI、EJBs、JMS等10.2Servlet根底10.2.1Servlet容器、Web效勞器和應用效勞器27servlet容器可以與web效勞器協(xié)作提供對servlet的支持一些servlet容器〔如ApacheTomcat〕自己也可以作為獨立的web效勞器運行隨著servlet和JSP的流行,一些主要的Web效勞器和應用程序效勞器都直接或者通過插件支持servlet和JSP。如:SunONEApplicationServerLotusDominoGoWebServerBEAweblogicTengahServerWebSphere應用效勞器JigsawNetForgeAcmeServerMotBaysJetty10.2Servlet根底10.2.1Servlet容器、Web效勞器和應用效勞器28ApacheTomcat5是servlet2.4和JSP2.0標準的官方參考實現(xiàn)完全免費,并且提供完整的源代碼可以到下載最新版本初始設置設置JAVA_HOME。假設JDK安裝在F:\ProgramFiles\Java\jdk1.6.0_10,可以仿照path和classpath的設置方法,新建一個環(huán)境變量:JAVA_HOME=F:\ProgramFiles\Java\jdk1.6.0_1010.2Servlet根底10.2.1Servlet容器、Web效勞器和應用效勞器
——ApacheTomcat5效勞器及其初始設置29為方便調(diào)試,還可進行如下設置啟動servlet重新載入功能〔所請求servlet類文件發(fā)生變化后,自動重新載入到效勞器內(nèi)存〕。翻開install_dir/conf/server.xml,在注釋<!--Definepropertiesforeachwebapplication-->后插入語句<DefaultContextreloadable=“true”/>開啟servlet調(diào)用器invokerservlet〔可以不修改Web應用的web.xml文件即可運行servlet〕。翻開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效勞器和應用效勞器
——ApacheTomcat5效勞器及其初始設置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>對于Tomcat6,還需在install_dir/conf/context.xml文件中,對Context節(jié)點添加“privileged="true"”屬性,如下:<Contextprivileged="true">…………</Context>10.2Servlet根底10.2.1Servlet容器、Web效勞器和應用效勞器
——ApacheTomcat5效勞器及其初始設置3110.2.2Web應用程序Web應用程序組成局部包括servlet、JSP及其支持文件這些組成局部需要進行部署通常部署在Tomcat的webapps子目錄中。一般其目錄結(jié)構(gòu)包括根目錄(contextroot)和幾個子目錄,也可以把子目錄捆綁到一個類型為war的存檔文件中10.2Servlet根底3210.2.2Web應用程序(續(xù))webapps子目錄一般包括,WEB-INF包含Web應用程序的部署描述文件(web.xml)在web.xml文件中配置Web應用程序??梢灾朴喐鞣N配置參數(shù):調(diào)用servlet的名稱、servlet的描述、servlet的完全的類名和servlet容器調(diào)用servlet的路徑修改web.xml的部署描述符后,需要重新啟動Tomcat效勞器WEB-INF/classes包括Web應用程序中所使用的servlet和實用工具類文件。如果類文件是包的組成局部,那么包的目錄結(jié)構(gòu)從該目錄開始WEB-INF/lib包含Java存檔文件(JAR文件),是servlet和實用工具類文件10.2Servlet根底3310.2.3ServletAPIServletAPI開發(fā)servlet和JSP程序,需要參考ServletAPI文檔包含javax.servlet和兩個包中所有servlet須實現(xiàn)接口,通常繼承如下兩個類中的一個GenericServletHttpServletServletGenericservletHttpservletMyservlet10.2Servlet根底34Servlet接口所有servlets必須實現(xiàn)這一接口Servlet接口的所有方法都是被自動調(diào)用的HttpServlet類覆蓋了接口的service方法service方法由servlet容器調(diào)用,對客戶端的請求作出響應。它會根據(jù)請求類型的不同自動調(diào)用doGet或doPost等方法能夠處理兩個最普通的HTTP請求類型doGet方法響應get請求doPost方法響應post請求10.2.3ServletAPI(續(xù))10.2Servlet根底3510.2.3ServletAPI(續(xù))HttpServletRequest接口由Web效勞器創(chuàng)立該接口的一個對象,并將其傳遞給servlet的service方法該類對象含有來自于客戶端的請求HttpServletResponse接口由Web效勞器創(chuàng)立該接口的一個對象,并將其傳送給servlet的service方法通過該類對象效勞器端可以對客戶端發(fā)出響應信息10.2Servlet根底3610.2.4Servlet的根本結(jié)構(gòu)Servlet的根本結(jié)構(gòu)一般擴展自HttpServlet覆蓋doGet或者doPost方法doGet或doPost都接收兩個類型的參數(shù):HttpServletRequest和HttpServletResponse通過HttpServletRequest,可以得到所有的輸入數(shù)據(jù),比方表單數(shù)據(jù)、HTTP請求報頭等客戶信息通過HttpServletResponse可以指定輸出信息由于doGet和doPost方法可能生成異常,必須在方法名稱后聲明拋出異?;蛘哂胻ry-catch語句處理異常10.2Servlet根底37GET請求是WEB瀏覽器請求的常見類型,用來請求Web頁面。本例中通過doGet方法處理GET請求。在doGet方法中通過HttpServletResponse對象得到PrintWriter,然后將一個文檔發(fā)給客戶。最終在客戶端生成一個網(wǎng)頁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編譯和安裝編譯——在設置好path和classpath的前提下,servlet的編譯和普通的java程序完全相同可以通過javac.exe編譯,比方可以在Dos環(huán)境下輸入:javacMyServlet.java也可以通過集成開發(fā)環(huán)境(IDE)編譯復制——編譯成功之后,將生成的類文件復制到相應的目錄下即可。在Tomcat效勞器上,此目錄可能是install_dir\webapps\ROOT\WEB-INF\classes\運行——啟動Tomcat效勞器,在地址欄輸入://localhost:8080/servlet/MyServlet10.2Servlet根底3910.3Servlet的生命周期首先效勞器僅創(chuàng)立servlet的一個實例創(chuàng)立servlet實例時,它的init方法都會被調(diào)用針對每個客戶端的每個請求,都會創(chuàng)立一個線程該線程調(diào)用servlet實例的service方法Service方法根據(jù)收到HTTP請求得類型,調(diào)用doGet,doPost或者其他方法多個并發(fā)請求,一般會導致多個線程同時調(diào)用service方法,通過單線程模式〔SingleThreadModel〕也可以規(guī)定任何時間僅允許一個線程運行最后,卸載servlet效勞器調(diào)用servlet的destroy方法4010.3Servlet的生命周期(續(xù))
——Servlet生命周期示意圖4110.3.1初始化servlet的初始化效勞器啟動,servlet被用戶首次調(diào)用,效勞器構(gòu)造servlet實例之后,即立刻調(diào)用init(ServletConfig)方法,執(zhí)行servlet實例的初始化工作ServeletConfig對象包含servlet初始化所需的很多參數(shù),比方計數(shù)器、默認值等init方法都會在servlet處理客戶請求(request)之前被調(diào)用一旦init方法被調(diào)用,只有效勞器通過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實例之前,需要先調(diào)用servlet的destroy方法釋放servlet所獲得的資源使servlet有時機關(guān)閉數(shù)據(jù)庫連接、停止后臺運行的線程、將cookie列表和點擊數(shù)寫入到磁盤執(zhí)行其他清理活動10.3Servlet的生命周期4410.4與客戶端交互HTTPservlet與客戶端的交互通過service方法處理客戶端的請求service方法根據(jù)請求(request)類型的不同,調(diào)用不同的方法對于GET請求,調(diào)用doGet()方法進行處理對于POST請求,調(diào)用doPost()方法進行處理4510.4.1提取Servlet信息注冊的servlet都有相關(guān)的很多初始化參數(shù)這些初始化參數(shù)寫在web.xml中。getInitParameter()方法可以得到servlet初始化的一些參數(shù)返回一個指定參數(shù)的值〔String類型〕如果指定參數(shù)不存在,那么返回nullgetInitParameterNames()方法可以得到初始化參數(shù)名稱返回String類型的Enumeration類型數(shù)據(jù)如果不存在初始化參數(shù),那么返回一個null的Enumeration10.4與客戶端交互46通過servlet初始化參數(shù)建立一個數(shù)據(jù)庫連接的程序段如下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ù))
——通過初始化建立數(shù)據(jù)庫連接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)的信息,同時可以將這些信息發(fā)送到客戶端getServerName()返回效勞器名稱getServerPort()返回效勞器監(jiān)聽端口getServerInfo()輸出效勞器程序和版本,之間用“/”分開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():得到客戶端機器的名稱利用InetAddress.getByName()方法可以將IP地址或客戶端機器名稱轉(zhuǎn)換成一個類型的對象InetAddressremoteInetAddress=InetAddress.getByName(req.getRemoteAddr());通過獲取客戶端的地址,并判斷是否隸屬某個范圍,可以限制某個地區(qū)的用戶訪問你的網(wǎng)站10.4與客戶端交互5110.4.3提取客戶端信息(續(xù))效勞器可以得到客戶想做的事情客戶請求表現(xiàn)為表單數(shù)據(jù),由“名/值”對組成。當提交某一個網(wǎng)頁的時候常常在瀏覽器地址欄中看到類似格式的數(shù)據(jù)格式name/value,每對之間用&隔開,表達式為param1=value1¶m2=value2¶m3=value3…request.getParameter:得到表單參數(shù)的值request.getParameterValues:得到屢次出現(xiàn)的參數(shù)值reques.getParameterNames:得到當前請求中所有參數(shù)的完整列表,調(diào)用形式如下publicStringServletRequest.getParameter(Stringname)publicString[]ServletRequest.getParameterValues(Stringname)10.4與客戶端交互52書本查詢的一個HTML網(wǎng)頁!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運行結(jié)果5510.4.4發(fā)送HTML信息Web效勞器響應(response)的構(gòu)成狀態(tài)行由版本(HTTP/1.1),一個狀態(tài)代碼(200)和一段對應狀態(tài)代碼的簡短消息(OK)組成一些響應報頭、Content-Type:text/html指定后面文檔MIME類型,后面的其他報頭可選。常用MIME類型有:text/html:HTML文檔text/plain:純文本text/xml:XMLimage/jpeg:JEPG圖像application/msword:MicrosoftWord文檔application/pdf:crobat文件application/zip:Zip檔案一個空行和響應的文檔10.4與客戶端交互56HTTP/1.1200OK //狀態(tài)行Content-Type:text/html //報頭Header2:……HeaderN:… //空行<!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.0Transitional//EN"> //文檔<HTML><HEAD>headcode</HEAD><BODY>…</BODY></HTML>10.4.4發(fā)送HTML信息(續(xù))10.4與客戶端交互57向客戶端輸出一個簡單網(wǎng)頁,顯示“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程序說明HelloWorld繼承了HttpServlet,然后重寫doGet方法在doGet方法中,首先將HTTPContent-Type響應報頭設置為text/html,即指定響應的類型為HTML文檔;然后通過getWriter()得到PrintWriter類型的一個對象out,按照HTML格式輸出一個簡單網(wǎng)頁運行結(jié)果10.4與客戶端交互客戶端跟蹤10.4.4發(fā)送HTML信息(續(xù))
——例10-4運行結(jié)果5910.5客戶端跟蹤客戶端跟蹤HTTP是無狀態(tài)協(xié)議,效勞器不能自動維護客戶連接的上下文信息許多情況下,Web效勞器必須要能夠跟蹤用戶的狀態(tài)比方購物網(wǎng)站和電子郵件網(wǎng)站,當用戶登錄以后,其身份和一系列的操作狀態(tài)都需要被跟蹤并保持servletAPI提供了兩種可以跟蹤客戶端狀態(tài)的方法CookieSession6010.5.1使用CookieCookie是Web效勞器保存在用戶硬盤上的一段文本,Web效勞器將它發(fā)送到瀏覽器之后,當再次訪問同一網(wǎng)絡時,瀏覽器將它原封不動的返回其中的信息片斷以‘名/值’對(name-valuepairs)的形式儲存使用這種方法,網(wǎng)站可以維護客戶的連接。這種用途可以表達在如下幾點在電子商務中標識用戶,實現(xiàn)短期跟蹤用戶記錄用戶名和用戶密碼,允許用戶下次自動登陸定制站點,記錄用戶的偏好定向廣告,記錄用戶感興趣的主題,并顯示與之相關(guān)的廣告10.5客戶端跟蹤61調(diào)用Cookie的構(gòu)造方法可創(chuàng)立一個cookie構(gòu)造方法接受兩個字符串參數(shù)cookie名稱cookie的值例如創(chuàng)立一個名為CookieName,值為John的cookie,可以使用下面的語句Cookielogin=newCookie(“CookieName”,”John”);10.5客戶端跟蹤10.5.1使用Cookie(續(xù))
——創(chuàng)立Cookie對象62創(chuàng)立了一個名為login的cookie之后,可通過很多現(xiàn)有的方法設置cookie的值和屬性可通過如下語句設置cookie的注釋:login.setComent(“YoucangetUserNameformthiscookie”);創(chuàng)立cookie并將它發(fā)送到瀏覽器后,默認情況下,它是會話級的cookie,僅僅存儲在瀏覽器內(nèi)存中,用戶退出瀏覽器后,cookie將被刪除;如果希望將cookie存儲在磁盤上,那么需要設定MaxAge,給出一個以秒為單位的生命周期,如下可以將生命設置為一天login.setMaxAge(60*60*24) //onedaysetPath(),setValue(),setVersion(),setDomain(),setSecure()等,相關(guān)的具體用法請查看servletAPI10.5客戶端跟蹤10.5.1使用Cookie(續(xù))
——設置Cookie屬性63剛創(chuàng)立的cookie存在于效勞器內(nèi)存中。必須將它發(fā)送到客戶端,cookie才能真正的發(fā)揮作用。發(fā)送cookie需要使用HttpServletResponse的addCookie方法,將cookie插入到一個HTTP響應報頭。發(fā)送的語句如下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,需要兩個步驟首先調(diào)用request.getCookies得到一個Cookie對象的數(shù)組然后調(diào)用每個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,如通過getValue方法得到相關(guān)cookie的值,設置MaxAge等10.5客戶端跟蹤10.5.1使用Cookie(續(xù))
——從客戶端讀取Cookie6510.5.2使用SessionSession一段時間內(nèi),單個客戶與web效勞器的一連串的交互過程在一個Session中客戶可能會屢次請求訪問同一個網(wǎng)頁,也有可能請求訪問各種不同的效勞器資源,其間用戶的狀態(tài)需要跟蹤并保持存在于效勞器端,不在網(wǎng)絡上傳送它的好處是可以用來記錄客戶端私有的信息,并且在時間范圍內(nèi)不會消失10.5客戶端跟蹤6610.5.2使用Session(續(xù))Session的使用可以分為三個步驟獲得一個session存儲數(shù)據(jù)到session或從session讀取數(shù)據(jù)銷毀session10.5客戶端跟蹤67通過調(diào)用ServletRequest的getSession方法可以得到一個sessionHttpSessionsession=request.getSession();為了保持正確的會話,必須在發(fā)送任何文檔到客戶程序之前獲得一個sessionpublicclassSessionServletextendsHttpServlet{publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{//Gettheuser'ssessionHttpSessionsession=request.getSession(true);//...out=response.getWriter();//...}}10.5客戶端跟蹤10.5.2使用Session(續(xù))
——獲得一個Session68SessionIDServlet容器為HttpSession分配的一個唯一標識符作為Cookie保存在客戶的瀏覽器中sessioncookie每次客戶發(fā)出HTTP請求時,Servlet容器可以從HttpRequest對象中讀取SessionID,然后根據(jù)SessionID在效勞器端找到相應的HttpSession對象,從而獲取客戶的狀態(tài)信息,這樣的cookie叫做sessioncookie存儲于瀏覽器內(nèi)存中的,并不寫到硬盤上的針對某一次會話而言,會話結(jié)束也就隨著消失了10.5客戶端跟蹤10.5.2使用Session(續(xù))
——存儲或讀取數(shù)據(jù)69URL重寫瀏覽器不支持Cookie,或者將瀏覽器設置為不接受Cookie的情況,可通過URL重寫來實現(xiàn)會話管理向URL連接添加參數(shù),并把sessionID作為值包含在連接中。為servlet響應局部的每個連接添加sessionID,可以使用一對方法response.encodeURL():使URL包含sessionIDresponse.encodeRedirectURL():使用重定向10.5客戶端跟蹤10.5.2使用Session(續(xù))
——存儲或讀取數(shù)據(jù)70從Session中讀取數(shù)據(jù)session.getAttribute(“name”)查找以前存儲的值如果不存在那么返回null在調(diào)用此方法返回的對象前,一定要檢查它是否為null向session中設置相關(guān)信息setAttribute替換掉此前設定的任何值removeAttribute移除而不是替換某個值10.5客戶端跟蹤10.5.2使用Session(續(xù))
——存儲或讀取數(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對象及其值自動銷毀在一段時間〔時間長短依賴與Web效勞器的設定〕沒有request的情況下,Web效勞器會自動銷毀session手動銷毀通過調(diào)用session的invalidate方法可以手動的銷毀sessionlogout在支持servlet2.4的效勞器中,可調(diào)用logout將客戶從Web效勞器中注銷,同時廢棄所有與該用戶相關(guān)聯(lián)的會話需要注意的是,這個動作會影響到此servlet之外的其他servlet,因此一定要與網(wǎng)站的其他開發(fā)人員協(xié)調(diào)使用10.5客戶端跟蹤10.5.2使用Session(續(xù))
——銷毀Session7310.6協(xié)作與通信協(xié)作與通信為了更好的響應客戶端的請求,servlet有時需要和網(wǎng)絡上的其他資源進行通訊,比方HTML網(wǎng)頁其他servletJSP網(wǎng)頁Servlet協(xié)作通訊的第一步是獲得分發(fā)器(dispatcher),即RequestDispatcher接口的一個對象74RequestDispatcher接口產(chǎn)生一個RequestDispatcher接口的對象RequestDispatcherdispatcher=getServletContext().getRequestDispatcher("/SomePath/SomeString");通過設置字符串參數(shù),可以獲得servlet,HTML網(wǎng)頁,JSP網(wǎng)頁等“資源”forward方法將本servlet的request請求傳遞給“其他資源”響應通過利用此方法可實現(xiàn):servlet先預處理request,然后將處理后的request傳遞給“其他資源”處理include方法引入“其他資源”來響應客戶端的請求10.6協(xié)作與通信(續(xù))
——RequestDispatcher接口75MyServlet1獲取另外一個servlet〔MyServlet2〕,并用它來響應用戶的請求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ā)送消息到效勞器對于動態(tài)網(wǎng)頁,Applet與Servlet的通訊尤為重要比方在一個聊天系統(tǒng)中,當一個用戶輸入了某些語句時,聊天室內(nèi)的所有其他用戶都可以看到。此功能可能的實現(xiàn)步驟是用戶先把消息發(fā)給效勞器然后效勞器發(fā)送給聊天室內(nèi)的所有用戶Applet和Servlet通訊的方式有多種通過socket直接建立網(wǎng)絡連接通過遠程方法調(diào)用(RemoteMethodInovation)通訊通過CORBA通訊10.6協(xié)作與通信80Socket通訊效勞器端的操作首先創(chuàng)立一個ServerSocket對象,在指定端口監(jiān)聽客戶端的request在接收到request后,accept()方法返回一個Socket對象通過socket對象創(chuàng)立輸入輸出流對象,并實現(xiàn)與客戶端的交互交互完畢后,關(guān)閉輸入輸出流和socket,最后關(guān)閉ServerSocker客戶端的操作首先創(chuàng)立socket對象,建立與效勞器的連接然后通過socket對象創(chuàng)立輸入輸出流,實現(xiàn)與效勞器的交互最后關(guān)閉輸入輸出流和socket10.6協(xié)作與通信10.6.1Applet與Servlet的通信(續(xù))
——Socket通訊81RMI通訊RemoteMethodInvocation的簡寫,即遠程方法調(diào)用通過存在于遠程機器上的對象,可以發(fā)消息給遠程的機器,且可以取得遠程機器程序執(zhí)行的結(jié)果。整個調(diào)用過程類似于此對象存在于本地機器,無疑這大大簡化了通訊過程當大量的數(shù)據(jù)是由效勞器端的對象動態(tài)提供時使用RMI通訊是非常適宜的如何使用RMI先定義一個繼承自的公用接口。在該接口中定義要求在效勞器上運行的方法接下來是實現(xiàn)遠程接口,遠程接口的實現(xiàn)類應該實現(xiàn):定義遠程對象的構(gòu)造方法,創(chuàng)立和安裝平安管理器,創(chuàng)立一個或多個遠程對象實例,并注冊至少一個遠程對象10.6協(xié)作與通信10.6.1Applet與Servlet的通信(續(xù))
——RMI通訊82通過CORBA通訊即公用對象請求代理體系〔CommonObjectRequestBrokerArchitecture〕,是OMA定義的一套和語言無關(guān)的分布式對象交換標準框架(Standardframeworkofobjectinteroperability)CORBA的主要功能是RPC(RemoteProcedureCall)式的支持,它使得本機對象可以調(diào)用遠端對象的方法使用方法類似于RMI定義接口創(chuàng)立類實現(xiàn)接口在效勞器上注冊后客戶就可以像本地對象一樣訪問遠程對象了10.6協(xié)作與通信10.6
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 合成材料制造過程中的安全與危險源控制考核試卷
- 天然氣開采業(yè)市場前景展望考核試卷
- 信息系統(tǒng)的農(nóng)業(yè)與農(nóng)村發(fā)展考核試卷
- 人力資源信息系統(tǒng)與數(shù)字化管理考核試卷
- 機場出行巴士租賃合同
- 醫(yī)療中心凈水機租賃合同協(xié)議書
- 礦產(chǎn)品加工招投標模擬探討
- 大型商場慶典舞蹈演員協(xié)議
- 酒店建設臨建房施工協(xié)議
- 交通運輸規(guī)劃招投標文件樣本
- 年度考核結(jié)果證明
- 教師招聘登記表
- 醫(yī)院消防安全知識培訓課件
- 《現(xiàn)代商務禮儀》課程標準(中職)
- ZX7系列手工焊機說明書
- 解放戰(zhàn)爭-第二次國共內(nèi)戰(zhàn)
- 一年級下冊美術(shù)說課稿-第19課 大樹的故事|冀美版
- 學生綜合素質(zhì)評價表
- 小學綜合實踐活動- 7.我是“非遺”小傳人教學設計學情分析教材分析課后反思
- 現(xiàn)場變更工程量確認單
- 供應商審廠管理規(guī)定
評論
0/150
提交評論