Edzy_Java

            BlogJava :: 首頁(yè) ::  ::  ::  :: 管理 ::
            58 隨筆 :: 12 文章 :: 11 評(píng)論 :: 0 Trackbacks

          1 Java Servlet簡(jiǎn)介

          ? Java Servlet是J S P技術(shù)的基礎(chǔ),而且大型的We b應(yīng)用程序的開發(fā)需要Java Servlet和J S P配合才能完成,這里簡(jiǎn)單介紹S e r v l e t的相關(guān)知識(shí),S e r v l e t的開發(fā)將在其它章節(jié)講述。

          ? S e r v l e t這個(gè)名稱大概源于A p p l e t,現(xiàn)在國(guó)內(nèi)的翻譯方式很多,本書為了避免誤會(huì),決定直接采用S e r v l e t而不做任何翻譯,讀者如果愿意,可以稱之為“小服務(wù)程序”。S e r v l e t其實(shí)和傳統(tǒng)的C G I程序和I S A P I、N S A P I等We b程序開發(fā)工具的作用是相同的,在使用Java Servlet以后,用戶不必再使用效率低下的C G I方式,也不必使用只能在某個(gè)固定We b服務(wù)器平臺(tái)運(yùn)行的A P I方式來(lái)動(dòng)態(tài)生成We b頁(yè)面。許多We b服務(wù)器都支持S e r v l e t,即使不直接支持S e r v l e t的We b服務(wù)器也可以通過(guò)附加的應(yīng)用服務(wù)器和模塊來(lái)支持S e r v l e t。得益于J a v a的跨平臺(tái)的特性, S e r v l e t也是平臺(tái)無(wú)關(guān)的,實(shí)際上,只要符合Java Servlet規(guī)范, S e r v l e t是完全平臺(tái)無(wú)關(guān)且是We b服務(wù)器無(wú)關(guān)的。由于Java Servlet內(nèi)部是以線程方式提供服務(wù),不必對(duì)于每個(gè)請(qǐng)求都啟動(dòng)一個(gè)進(jìn)程,并且利用多線程機(jī)制可以同時(shí)為多個(gè)請(qǐng)求服務(wù),因此Java Servlet效率非常高。

          ? 但Java Servlet也不是沒(méi)有缺點(diǎn),和傳統(tǒng)的C G I、I S A P I、N S A P I方式相同,Java Servlet是利用輸出H T M L語(yǔ)句來(lái)實(shí)現(xiàn)動(dòng)態(tài)網(wǎng)頁(yè)的,如果用Java Servlet來(lái)開發(fā)整個(gè)網(wǎng)站,動(dòng)態(tài)部分和靜態(tài)頁(yè)面的整合過(guò)程簡(jiǎn)直就是一場(chǎng)惡夢(mèng)。這就是為什么S U N還要推出Java Server Pages的原因。

          1.1 JSPServlet

          ? Servlet (服務(wù)器小程序)是一個(gè)與協(xié)議無(wú)關(guān)的跨平臺(tái)的服務(wù)器組件。如同APPlet(小程序)被集成到web測(cè)覽器中一樣,它被集成到服務(wù)器中,可以實(shí)現(xiàn)網(wǎng)絡(luò)遠(yuǎn)程動(dòng)態(tài)加載。 最初,主要是把Servlet集成到支持HTTP協(xié)議的Web服務(wù)器上,但是隨著它的不斷改進(jìn) 現(xiàn)在巳經(jīng)集成到實(shí)現(xiàn)Java服務(wù)器API的任何服務(wù)上了。同時(shí),Servlet也是實(shí)現(xiàn)智能代理的第一步。JSP主要關(guān)注于HTML(或者XML)與Java代碼的結(jié)合,以及加入其中的JSP 標(biāo)記。如果一個(gè)支持JSP的服務(wù)器遇到一個(gè)JSP頁(yè)面,它首先查看該頁(yè)面是否被編譯成為一個(gè)Servlet。由此可見(jiàn),JSP首先被編譯成Servlet,即被轉(zhuǎn)變?yōu)榧僇ava 然后被裝載到服務(wù)器執(zhí)行。當(dāng)然,這一過(guò)程根據(jù)不同的JSP引擎而略有不同。下面是Servlet的一些應(yīng)用范圍:

          (1)用于處理HTML表單。通過(guò)HTTP產(chǎn)生提交表本數(shù)據(jù),包括買賣訂單或信用卡數(shù)據(jù)。Servlet可以成為訂單處理系統(tǒng)的一部分,和產(chǎn)品存貨數(shù)據(jù)庫(kù)一道工作,也可以用 在在線支付系統(tǒng)上。

          (2)允許人們之間的合作。一個(gè)Servlet能并發(fā)處理多個(gè)請(qǐng)求,人們可以使用在諸如在線會(huì)議這樣的同步請(qǐng)求支持系統(tǒng)。

          (3)轉(zhuǎn)送請(qǐng)求。Servlet可以轉(zhuǎn)送請(qǐng)求給其他的服務(wù)器和Servlet。這就允許在鏡像同樣內(nèi)容的幾個(gè)服務(wù)器之間平衡負(fù)載。按照任務(wù)類型或組織范圍,可以允許被用來(lái)在幾個(gè)服務(wù)器中劃分邏輯上的服務(wù)器。

          (4)Servlet編寫者們可以定義彼此之間共同工作的激活代理。每個(gè)代理者是一個(gè)Servlet,而且代理者能夠在他們之間傳送數(shù)據(jù)。

          1.2 Java Servlet的優(yōu)點(diǎn)

          ? Java Servlets比傳統(tǒng)的CGI或其他CGI類似替代技術(shù)來(lái)說(shuō),只有工作效率更管使用更方便、功能更強(qiáng)大、更小巧也更便宜等優(yōu)點(diǎn)。下面將具體介紹這些優(yōu)點(diǎn)。

          1.效率高

          ? 傳統(tǒng)CGI對(duì)每一個(gè)HTTP請(qǐng)求都要產(chǎn)生一個(gè)新的進(jìn)程。即使某個(gè)CGI程序是一個(gè)執(zhí)行非常快的操作,打開進(jìn)程的時(shí)間也占用了大部分執(zhí)行時(shí)間。而對(duì)Java Servlets來(lái)說(shuō),在 Java虛擬機(jī)上每一個(gè)請(qǐng)求由一個(gè)""Java線程(thread)響應(yīng),而不是一個(gè)"大"操作系統(tǒng)進(jìn)程。類似地,傳統(tǒng)CGI如果對(duì)同一個(gè)CGI程序有N個(gè)同時(shí)請(qǐng)求,這個(gè)CGI程序的代碼將被導(dǎo)人內(nèi)存N次。Java Servlets產(chǎn)生N個(gè)線程 但只有一個(gè)Java Servlets Class的Copy。同時(shí)Java Servlets比CGI有更多的優(yōu)化選擇,像預(yù)先計(jì)算、打開數(shù)據(jù)庫(kù)連接等。

          2.使用方便

          ? Java Servlets具有自動(dòng)粘貼和解碼HTML表單數(shù)據(jù)、讀和設(shè)置HTTP頭、處理 Cookies、 跟蹤Session等其他大量功能。

          3.功能強(qiáng)大

          ?Java Servlets可以很容易地實(shí)現(xiàn)對(duì)CGI來(lái)說(shuō)不可能或很困難的事務(wù)。如Java Servlets 能直接和服務(wù)器進(jìn)行通信,而CGI不能。

          4.共享數(shù)據(jù)

          ? Java Servets之間能共享數(shù)據(jù)很容易實(shí)現(xiàn)數(shù)據(jù)庫(kù)連接池。它能方便地實(shí)現(xiàn)管理Request 請(qǐng)求,簡(jiǎn)化Session和獲取前一頁(yè)面信息的操作。而在CGI之間通信則很差。由于每個(gè)CGI 程序的調(diào)用都開始一個(gè)新的進(jìn)程;調(diào)用間通信通常要通過(guò)文件進(jìn)行,因而相當(dāng)緩慢。同一臺(tái)服務(wù)器上的不同CGI程序之間的通信也相當(dāng)麻煩。

          5.調(diào)用時(shí)間短

          ? CGI程序是作為單獨(dú)過(guò)程運(yùn)行的,通常調(diào)用時(shí)間較長(zhǎng)。這個(gè)進(jìn)程在每次調(diào)用的時(shí)候都要發(fā)生,而在使用解釋器的時(shí)候調(diào)用時(shí)間會(huì)更長(zhǎng)。與此相比,內(nèi)存中的Servlet可以非常迅速地加載。

          6.安全

          ? 有些CGI版本具有明顯的安全弱點(diǎn)。即使是使用最新的標(biāo)準(zhǔn)利PERL等語(yǔ)言,系統(tǒng)也沒(méi)有基本安全框架,要靠一組事實(shí)上的規(guī)則。而Java定義有完整的安全機(jī)制,包括SSL、CA認(rèn)證和安全政策等規(guī)范。

          7.小巧

          ? Java Servlets使用Java編寫,遵循標(biāo)準(zhǔn)API。它能直接或借助插件在幾乎所有Web 服務(wù)器上運(yùn)行。

          8. 價(jià)格低

          ? 現(xiàn)在有很多都是免費(fèi)軟件或者共享軟件。

          1.3 Servlet的結(jié)構(gòu)

          ? 在具體掌握Servlet之前,需要對(duì)Java語(yǔ)言有所了解。下面的介紹需要用戶了解Java基礎(chǔ),在Servlet API中最重要的是Servlet interface。所有的Servlet都執(zhí)行這個(gè)interface(接口)其執(zhí)行方式有兩種:直接的執(zhí)行方式或者通過(guò)擴(kuò)展類(Class)的執(zhí)行方式,如HttpServlet。這個(gè)Servlet interface提供安排Servlet與客戶端聯(lián)系的方法。Servlet編寫者可以在開發(fā)Servlet程序時(shí)提供更多一些這樣的方法。

          ? 當(dāng)一個(gè)servlet接收來(lái)自客戶端的調(diào)用請(qǐng)求時(shí),它接收兩個(gè)對(duì)象類,一個(gè)是 ServletRequest,另外一個(gè)是ServletResPonse。ServletRequest類概括從客戶端到服務(wù)器之間的聯(lián)系,而ServletResPonse類概括從Servlet返回客戶端的聯(lián)系。

          ? ServletRequest接口可以獲取到這樣一些信息,如由客戶端傳送的闡述名稱、客戶端正在使用的協(xié)議、產(chǎn)生請(qǐng)求并且接收請(qǐng)求的服務(wù)器遠(yuǎn)端主機(jī)名等。它也提供獲取數(shù)據(jù)流的Servlet和ServletInputstream.這些數(shù)據(jù)是客戶端引用中使用HTTP POST和PUT方法遞交的。一個(gè) ServletRequest的子類可以讓Servlet獲取更多的協(xié)議特性數(shù)據(jù),例如 HttpservletRequest包含獲取HTTP-specific頭部信息的方法。

          ? ServletResponse接口給出相應(yīng)客戶端的Servlet方法。它允許Servlet設(shè)置內(nèi)容長(zhǎng)度和回應(yīng)的MIME(MultiPurpose Internet Mail Extensions)類型,并已提供輸出流 Servletoutputstream 通過(guò)編寫者可以發(fā)回相應(yīng)數(shù)據(jù)。ServletResponse子類可以給出更多protocol-specific容量的信息例如HttpServletResponse包含允許Servlet操作HTTP-specific頭部信息的方法。

          ? 上面有關(guān)類和接口的描述構(gòu)成了一個(gè)基本的Servlet框架。HTTP Servlet有一些附加的可以提供 Servlet-tracking capabilities的方法。Servlet編寫者可以用這些API在有他人操作時(shí)維護(hù)Servlet與客戶端之間的狀態(tài)。Servlet都是由HttpServlet繼承下來(lái)的,其基本結(jié)構(gòu)如下面的代碼所示:

          import java.io.*;
          i
          mport javax.servlet.*;
          import javax.servlet.http.*;
          public class SomeServlet extends HttpServlet
          {
          ? ?public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException
          ? {//"request"可以讀取輸入的值比(e.g.cookies)
          ?? //
          和表單提交的數(shù)據(jù)
          ?? //"response"返回輸出的內(nèi)容
          ????? PrintWrite out=response.getwriter();
          ?? //
          "Out"向例覽器寫內(nèi)容。
          ? }
          }

          1.4 Java Servlet接口

          ?Servlet從javax包的httpservlet類擴(kuò)展,在Httpservlet中加入了一些附加的方法,這些方法可以被協(xié)助處理HTTP基本請(qǐng)求的Httpservlet類中的方法Service自動(dòng)調(diào)用。這些方法有:

          1.doGet用來(lái)處理HTTP的Get請(qǐng)求

          ? 這個(gè)Get請(qǐng)求僅僅允許客戶從HTTP Server上“取得”(get)資源。重載此方法的用戶自動(dòng)允許支持方法Head。這個(gè)Get請(qǐng)求被認(rèn)為是安全的,沒(méi)有任何的副面影響,對(duì)用戶來(lái)說(shuō)是很可靠的,比如大多數(shù)的正規(guī)查詢都沒(méi)有副作用。如果想要改變存儲(chǔ)數(shù)據(jù)的請(qǐng)求必須用其他的HTTP方法。這要求方法也必須是安全的操作。方法doGet的默認(rèn)執(zhí)行將返回一個(gè) HTTP的BAD_REQUEST錯(cuò)誤。

          ? 方法doGet的格式:
          protected void doGet(HttpServletResqucst request, HttpServletResPonse response)
          throws ServletException, IOException;

          2.doPost用來(lái)處理HTTP的Post請(qǐng)求

          這個(gè)Post請(qǐng)求包含了在必須通過(guò)此Servlet執(zhí)行的請(qǐng)求中的數(shù)據(jù)。由于它不能立即取得資源 故對(duì)于那些涉及到安全性的用戶來(lái)說(shuō),通過(guò)Post請(qǐng)求操作會(huì)有一些副作用。

          ? 方法doPost的默認(rèn)執(zhí)行將返回一個(gè)HTTP的BAD_REQUEST錯(cuò)誤。當(dāng)編寫Servlet時(shí),為了支持Post操作必須在于類HttpServlet中執(zhí)行此方法。

          此方法的格式:
          Protected void doPost(HttpServletRequest requst,
          ?? HttpServletResPonse response)
          ?throws ServletException,IOException;

          3 doPut用來(lái)處理HTTP的Put請(qǐng)求

          ? 此Put請(qǐng)求模擬通過(guò)FTP發(fā)送一個(gè)文件。對(duì)于那些涉及到安全性的用戶來(lái)說(shuō),通過(guò)Put請(qǐng)求操作也會(huì)有一些副作用。

          ? 此方法的格式:
          Protected void doPut(HttpServletResquest requcst,
          ? HttpServletResPonse response)
          ?throws ServletExcePtion,IOException;

          4.doDelete用來(lái)處理HTTP的Delete請(qǐng)求

          ? 此方法允許客戶端請(qǐng)求一個(gè)從Server移出的URL。對(duì)于那些涉及到安全性的用戶來(lái)說(shuō),通過(guò)Delete請(qǐng)求操作會(huì)有一些副作用。

          ? 方法 doDelete的默認(rèn)執(zhí)行將返回一個(gè)HTTP的.BAD_REQUEST錯(cuò)誤。當(dāng)編寫Servlet時(shí),為支持 Delete請(qǐng)求,必須在子類 HttpServlet中執(zhí)行此方法。

          ? 此方法的格式:
          protected void doDelete(HttpServletResquest request,
          ?HttpServletResPonse response)
          ? throws ServletException,IOException;

          5. doHead用來(lái)處理 HTTP的 Head請(qǐng)求

          ? 默認(rèn)地,它會(huì)在無(wú)條件的Get請(qǐng)求執(zhí)行時(shí)期中運(yùn)行,但不返回任何數(shù)據(jù)到客戶端,只返回包含內(nèi)容信息的長(zhǎng)度的Header。由于用到Get請(qǐng)求,此方法應(yīng)該是很安全的(沒(méi)有副作用),也是可重復(fù)使用的。此方法的默認(rèn)執(zhí)行自動(dòng)地處理了HTTP的Head請(qǐng)求,并且不需要通過(guò)一個(gè)子類執(zhí)行。

          ? 此方法的格式:
          p
          rotected void doHead(HttpServletResquest request,
          ?HttpServletResPonse response)
          ? throws ServletException,IOException;

          6. doOptions用來(lái)處理HTTP的Options請(qǐng)求

          ? 此方法自動(dòng)決定支持什么HTTP方法。比如說(shuō),如果一個(gè)Servlet的作者創(chuàng)建HttPServlet 的子類并重載方法doGet,然后方法doOption會(huì)返回下面的header:

          ? Allow:GET,HEAD,TRACE,OPTIONS

          ? 一般不需要重載方法doOptions。

          ? 此方法的格式:
          p
          rotected void doOption(HttpServletResquest request,
          ?HttpServletResPonse response)
          ? throws ServletException,IOException;

          7.doTrace用來(lái)處理HTTP的Trace請(qǐng)求

          ? 此方法的默認(rèn)執(zhí)行產(chǎn)生一個(gè)包含所有在Trace請(qǐng)求中的header信息的應(yīng)答。在開發(fā)Servlet時(shí),多數(shù)情況下需要重載此方法。

          ? 此方法的格式:
          p
          rotected void doHead(HttpServletResquest request,
          ?HttpServletResPonse response)
          ? throws ServletException,IOException;

          ? 在開發(fā)以HTTP為基礎(chǔ)的servlet中,方法doGet和方法doPost是最重要的。

          1.5 Servlet的生命周期

          ? Servet程序可以說(shuō)是在服務(wù)器端運(yùn)行的Applet,甚至比Applet更為簡(jiǎn)單,因?yàn)镾ervlet 不需要考慮圖形界面的應(yīng)用。與Applet一樣 Servlet也有一個(gè)生命周期。Servet的生命周期是當(dāng)服務(wù)器裝載運(yùn)行Servlets,接收來(lái)自客戶端的多個(gè)請(qǐng)求并且返回?cái)?shù)據(jù)給客戶端。然后再刪除Servlet。

          ? 詳細(xì)描述如下:

          1. 初始化時(shí)期

          ? 當(dāng)一個(gè)服務(wù)器裝載Servlet時(shí),它運(yùn)行Servlet的init()方法。

          public void init(ServletConfig config)throws ServetException
          {super.init();//一些初始化的操作,如數(shù)據(jù)庫(kù)的連接}

          ? 需要記住的是,一定要在init()程序的最后調(diào)用super.imit()init()方法不能被反復(fù)調(diào)用,一旦調(diào)用就重新裝載Servlet;也就是說(shuō),直到服務(wù)器調(diào)用Destroy方法卸載Servlet后才能再次被調(diào)用。

          2. Servet的執(zhí)行時(shí)期

          ? 在服務(wù)器裝載初始化Servet后,Servlet就能夠處理客戶端的請(qǐng)求。用Servlet方法可以很容易做到這一點(diǎn)。每個(gè)客戶端請(qǐng)求有其自己Service方法,這些方法接收客戶端請(qǐng)求。并且發(fā)回相應(yīng)的響應(yīng)。Servlets能同時(shí)運(yùn)行多個(gè)Service 這是很重要的。這樣,Service 方法可以按一個(gè)thread-safe樣式編寫,如service方法更新servet對(duì)象中的一個(gè)字段Field,這個(gè)字段可以同時(shí)存取的。假如某個(gè)服務(wù)器不能同時(shí)并發(fā)運(yùn)行Service方法,也可以用SingleThreadModel interface。這個(gè)接口保證不會(huì)有兩個(gè)以上的線程并發(fā)運(yùn)行。在Servlet執(zhí)行期間其最多的應(yīng)用是處理客戶端的請(qǐng)求,并產(chǎn)生一個(gè)網(wǎng)頁(yè)。其代碼如下:

          ...
          PrintWriter out = response.getWriter();//輸出的資料
          out.println("<html>");
          out.println("<head><title>"#Servlet</title></head>");
          out.println("<body>:);
          out.println("<h1>嗨!! Hello Worid.</h1>");
          out.println("</body></html>");
          out.close();
          ...

          ? 執(zhí)行時(shí)期分為數(shù)類,分別是對(duì)應(yīng)HTTP方法中的Get、Post時(shí)等方法 例如doGet()對(duì)應(yīng)到Get或者doPost()對(duì)應(yīng)到Post方法。其他對(duì)應(yīng)的方法可以參照 Servlet API文件的說(shuō)明。

          3. servet結(jié)束時(shí)期

          ? Servlets一直運(yùn)行到它們被服務(wù)器卸載。在init()方法中,可能開啟了某些資源,當(dāng)網(wǎng)頁(yè)伺服系統(tǒng)要重新啟動(dòng),或者是要收回資源時(shí)就會(huì)呼叫destroy()這個(gè)方法收回在nit()方法中使用的資源。因此如果需要在結(jié)束時(shí)關(guān)閉一些資源,同樣也是重載這個(gè)方法。即,也要呼叫 super.destroy(),不過(guò)大部分的時(shí)候都是不需要的。

          public void destroy()
          {
          //
          回收在init()中啟用的資源,如關(guān)閉數(shù)據(jù)庫(kù)的連接等。
          }

          1.6 使用Servlets的兩種模式

          ? 當(dāng)JSP成為開發(fā)動(dòng)態(tài)網(wǎng)站的主要技術(shù)時(shí),為何在JSP技術(shù)中不強(qiáng)調(diào)Servets呢?因?yàn)?span lang="en-us">Servlets的應(yīng)用是沒(méi)有問(wèn)題的,它們非常適于服務(wù)器端的處理和編程,并且會(huì)長(zhǎng)期保持現(xiàn)狀。從結(jié)構(gòu)上說(shuō),可以將JSP看作是Servlet的一個(gè)高層的抽象實(shí)現(xiàn)。特別是在servlet 2.2 API下。但是用戶仍然不能無(wú)拘束地使用Servlet.因?yàn)樗鼈儾⒉贿m合每一個(gè)人,例如頁(yè)面設(shè)計(jì)者可以方便地使用HTML或者XML具開發(fā)JSP頁(yè)面,但SerVet卻更適合于后端開發(fā)者使用,他們的工具是IDE--一個(gè)需要更多編程訓(xùn)練的開發(fā)領(lǐng)域。當(dāng)發(fā)布Servlet時(shí),每個(gè)開發(fā)者必須小心地確定在頁(yè)面表現(xiàn)和頁(yè)面邏輯之間沒(méi)有緊密的關(guān)聯(lián)出現(xiàn)。用戶可以使用第三方HTML包裝工具,如htmlkona來(lái)混合HTML和servlet代碼。即使如此,這點(diǎn)靈活性還不足以讓用戶自由地改變風(fēng)格本身。例如,如果希望從html改變到dhtml則需要小心測(cè)試包裝本身,以確保新的格式可以正確使用。在最壞的情況下,包裝不可用,那就需要應(yīng)變馬來(lái)表現(xiàn)動(dòng)態(tài)內(nèi)容。所以,需要一種新的解決方案--混合JSP和Servlets的使用。

          ? 早期的JSP標(biāo)準(zhǔn)給出了兩種使用JSP的方式。這些方式 都可以歸納為JSP模式1和JSP模式2,主要的差別在于處理大量請(qǐng)求的位置不同。

          ? 在模式1中,JSP頁(yè)面獨(dú)自響應(yīng)請(qǐng)求并將處理結(jié)果返回客戶。這里仍然有表現(xiàn)和內(nèi)容的分離,因?yàn)樗械臄?shù)據(jù)依靠Beans來(lái)處理。盡管模式1可以很好的滿足小型應(yīng)用的需要,但卻不能滿足大型應(yīng)用的要求。大量使用模式1,常常會(huì)導(dǎo)致頁(yè)面被嵌人大量的Script或者Java代碼。特別是當(dāng)需要處理的商業(yè)邏輯很復(fù)雜時(shí) 情況會(huì)變得嚴(yán)重。也許對(duì)于Java 程序員來(lái)說(shuō),這不算大的問(wèn)題。但如果開發(fā)者是前端界面設(shè)計(jì)人員——在大型項(xiàng)目中, 這很常見(jiàn),則代碼的開發(fā)和維護(hù)將出現(xiàn)困難。在任何項(xiàng)目中,這樣的模式多少總會(huì)導(dǎo)致定義不清的響應(yīng)和項(xiàng)目管理的困難。

          ? JSP模式2是一種面向動(dòng)態(tài)內(nèi)容的實(shí)現(xiàn),結(jié)合了Servlet和JSP技術(shù)。它利用了兩種技術(shù)原有的優(yōu)點(diǎn),采用JSP來(lái)表現(xiàn)頁(yè)面,采用Servlets來(lái)完成大量的處理。這里Servlet扮演一個(gè)控制者的角色;并負(fù)責(zé)響應(yīng)客戶請(qǐng)求。接著,Servlet創(chuàng)建JSP需要的bean和對(duì)象,再根據(jù)用戶的行為,決定將那個(gè)JSP頁(yè)面發(fā)送給用戶。特別要注意,JSP頁(yè)面中沒(méi)有任何商業(yè)處理邏輯,它只是簡(jiǎn)單地檢索Servlet先前創(chuàng)建的Beans或者對(duì)象,再將動(dòng)態(tài)內(nèi)容插入預(yù)定義的模版。從開發(fā)的觀點(diǎn)看,這一模式具有更清晰的頁(yè)面表現(xiàn),清楚地劃分開發(fā)者角色,可以充分地利用開發(fā)小組中的界面設(shè)計(jì)人員。事實(shí)上 越是復(fù)雜的項(xiàng)目,采用模式2的好處就越突出。

          ? 使用模式2,JSP和Servlet可以在功能上最大限度的分開。正確地使用模式2,產(chǎn)生一個(gè)中心化的控制Servlet,并且只完成顯示的JSP頁(yè)面。另一方面,模式2的實(shí)現(xiàn)很復(fù)雜。因此,在簡(jiǎn)單的應(yīng)用中,可以考慮使用模式l。

          2 創(chuàng)建Servlet程序

          ? Servlet程序使用的語(yǔ)言為Java語(yǔ)言,保存時(shí)需要以“*.java”為擴(kuò)展名。在運(yùn)行Servlet程序之前,必須對(duì)其進(jìn)行編譯。以下將詳細(xì)介紹如何使用Java編譯器對(duì)Servlet進(jìn)行編譯以及如何在JSP程序中加入Servlet程序。

          2.1 如何運(yùn)行Servlet程序

          ? Java Servlets不像JSP那樣,在第一次訪問(wèn)時(shí)服務(wù)器自動(dòng)編譯,它需要手動(dòng)編譯。在JDK環(huán)境下。可以用命令行程序“javac.exe 編譯。編譯時(shí)使用javac命令:

          javac<選項(xiàng)><源文件>

          ?包括下面選項(xiàng):

          -g Generate all debugging info
          -g:none Generate no debugging info
          -g:{lines,vars,soure} Geaerate only some debugging info
          -O Optimize;may hinder debugging or enlarge class files
          -nowarn Generate no warnings
          -verbose Output messages about what the compiler is doing
          -deprecation Output source locations where deprecated APIs are used
          -CLASSPATH<path> Specify where to find user class files
          -sourcepath<path> Specify where to find input soure files
          -bootCLASSPATH<path> Override location of bootstrap class files
          -extdirs Override location of installed extension
          -d<directory> Specify where to place generated c1ass files
          -enceoding<encoding> Specify character encoding used by source files
          -target Generate class files for specific VM version

          ? 執(zhí)行Servlet的必備條件是一個(gè)Web Server與Servlet的執(zhí)行引擎。而JSWDK既是Servlet引擎,也包含了一個(gè)簡(jiǎn)單的Web Server。各種Servlet引擎在對(duì)應(yīng)Servlet時(shí),用的都是差不多的做法。通常都是用URL對(duì)應(yīng)的方式,將以/servlet開頭的URL交給Servlet 引擎處理。例如,當(dāng)網(wǎng)頁(yè)的Server與Servlet引擎啟動(dòng)后,網(wǎng)頁(yè)Server將所有向它請(qǐng)求的URL(例如http://locwhost:8080/servlet/helloworidservlet)交給Servlet引擎處理,Servlet引擎就會(huì)向指定給它的servtet目錄尋找servlet的類別碼,然后將其載入。tomcat的Servlet放置目錄應(yīng)該是在以下路徑:

          C:\jspstudy\tomcat\root\Web-INF\classes

          ? 其中,C:\jspstudy\tomcat\是各用戶安裝tomcat的目錄,tomcat預(yù)設(shè)安裝的情況來(lái)看,上面的目錄包含的內(nèi)容如圖3-2所示。凡是Servlet的程序編譯成class文件以后,只要放在這個(gè)目錄下,就可以通過(guò)URL來(lái)取得它。Tomcat的主要配置文件為server.xml,請(qǐng)?jiān)敿?xì)查看該文件。

          ? 關(guān)于Tomcat的配置請(qǐng)參看“Tomcat全攻略”。

          2.2 第一個(gè)Servlet程序

          ? 為了更清楚地理解Servlets是如何工作的,下面來(lái)詳細(xì)地看一個(gè)Servlet示例。程序 Hellow.java簡(jiǎn)單向客戶端輸出信息。

          文件hellow.java:

          import java.io.*;
          import java.text.*;
          import java.util.*;
          import javax.servlet.*;
          import javax.servlet.http.*;
          public class hellow extends HttpServlet {
          ? public void service(HttpServletRequest request,HttpServletResponse ?? response) throws IOException,ServletException
          ?{
          ? response.setContentType("text/html");
          ? PrintWriter out = response.getWriter();
          ? out.println("<html>");
          ? out.println("<head>");
          ? String title="Hello World";
          ? out.println("<title>"+ title +"</title>");
          ? out.println("</head>");
          ? out.println("<body bgcolor=\"white\">");
          ? out.println("<h1>" + title + "/h1>");
          ? out.println("</body>");
          ? out.println("</html>");
          ?}
          }
          ?在命令行鍵人“javac Hellow.java”。如果沒(méi)有任何提示的話就是運(yùn)行通過(guò)了。執(zhí)行后會(huì)在同一個(gè)目錄里生成一個(gè) Hellow.lass文件,為了在瀏覽器里執(zhí)行Hellow Servlet需要把該class文件放在Tomcat安裝目錄\webapps\ROOT\WEB-INF\classes\目錄下。在測(cè)覽器中用httP://localhost:8080/servlet/hellow就可以執(zhí)行 Hellow servlet了 執(zhí)行結(jié)果見(jiàn)演示或教材圖3-3。如果編譯不通過(guò),請(qǐng)注意Java程序的大小寫問(wèn)題。如果不是語(yǔ)法錯(cuò)誤的話,一般就是因?yàn)檎也坏较鄳?yīng)的環(huán)境變量。如果是這種錯(cuò)誤,可以在操作系統(tǒng)的環(huán)境變量CLASSPATH 中加人教材36頁(yè)上半部分的代碼。注意,可以把這些文件集中放到一個(gè)文件夾下,以免太分散。

          3 Servlet處理表單提交

          3.1 表單的基本概念

          ? HTML 表單的作用在于客戶和服務(wù)器的交互。用戶填寫完表單以后按提交(英文為submit), 中文通常為“確定”或“提交”按鈕,表單中的信息將被發(fā)送到服務(wù)器端進(jìn)行處理。服務(wù)器將處理過(guò)的用戶提供信息的HTML 文件返回到客戶端進(jìn)行顯示。

          3.1.1 什么是HTML 表單

          ? 在Web 上獲取用戶的信息,大多數(shù)情況下都是通過(guò)表單來(lái)實(shí)現(xiàn)的。比如說(shuō)輸入消費(fèi)者的姓名、地址,或者輸入一個(gè)詞來(lái)使用搜索引擎查找,或者從來(lái)訪者處收集數(shù)據(jù)提供參考等等。

          1. HTML 表單的數(shù)據(jù)流

          ? 來(lái)訪者通過(guò)表單向JPS 引擎輸入了數(shù)據(jù),并保存在request 對(duì)象中,那么接下來(lái)怎么辦?圖3-3 展示了數(shù)據(jù)流是如何在服務(wù)器和客戶之間傳遞的(至少在SUN 的JSPrdference implementation 是這么做的,別的JPS 引擎工作起來(lái)可能會(huì)有一點(diǎn)點(diǎn)的不同,其實(shí)大同小異都差不多)。

          ? 圖3-2,JSP 引擎把存放在request對(duì)象中的數(shù)據(jù)流發(fā)到JSP 頁(yè)面指定的服務(wù)器端的組件(JavaBeans 組件,servlet 或者enterprisebean), 組件收到這些個(gè)數(shù)據(jù)以后,有可能再存放這些數(shù)據(jù)到數(shù)據(jù)庫(kù)或者在其他的地方存放起來(lái),同時(shí),返回一個(gè)response 對(duì)象給JSP引擎。JSP 引擎再把response 對(duì)象傳給JSP 頁(yè)面,這時(shí)的頁(yè)面包含了定義好的格式和從服務(wù)器端得到的數(shù)據(jù)。這時(shí)JSP 引擎和Web 服務(wù)器再發(fā)送一個(gè)整理好的完整的頁(yè)面給客戶。也就是我們?cè)跒g覽器上看到的結(jié)果。客戶和服務(wù)器間的通信協(xié)議可以用HTTP 當(dāng)然也可以用其他的協(xié)議。

          ? Request 和Response 對(duì)象在你制作的JSP 源代碼中起作用

          3.1.2 HTML 表單的運(yùn)行原理

          ? 客戶端的瀏覽器從服務(wù)器獲取HTML 頁(yè)面時(shí),實(shí)際上使用HTTP 協(xié)議(Hypertext Transfer Protocol)。 HTTP 協(xié)議規(guī)定了信息在Internet 上的傳輸方法特別規(guī)定了瀏覽器與服務(wù)器的交互方法。

          ? 在瀏覽器從服務(wù)器獲取頁(yè)面的過(guò)程中,瀏覽器在網(wǎng)站上打開了一個(gè)對(duì)Internet 服務(wù)器的連接并發(fā)出請(qǐng)求服務(wù)器收到請(qǐng)求后給予回應(yīng)所以HTTP 協(xié)議又被稱為請(qǐng)求和響應(yīng)協(xié)議。

          ? 所有的瀏覽器和服務(wù)器間的通信都發(fā)生在離散的“請(qǐng)求──響應(yīng)”對(duì)中瀏覽器必須發(fā)出請(qǐng)求才開始通信,服務(wù)器角色完全是被動(dòng)的,它必須在被請(qǐng)求后起作用。

          ? 一個(gè)典型請(qǐng)求通常包含許多頭。頭提供了關(guān)于消息內(nèi)容的附加信息以及請(qǐng)求的來(lái)源。其中有些頭是標(biāo)準(zhǔn)的,其他的是有關(guān)特定瀏覽器的。

          ? 一個(gè)請(qǐng)求還包含信息體。例如,若請(qǐng)求用POST方法而不是GET方法,信息體可以包含HTML 表單的內(nèi)容。在HTML 表單上單擊submit 鍵時(shí),該表單使用ACTION = “POST”特征,輸入表單的內(nèi)容都被發(fā)送到服務(wù)器上。該表單的內(nèi)容就由POST 方法在請(qǐng)求的信息體中發(fā)送。

          ? 服務(wù)器收到請(qǐng)求時(shí)返回HTTP 響應(yīng)。每個(gè)響應(yīng)都由狀態(tài)行開始可以包含幾個(gè)頭及可能的信息體。

          對(duì)頁(yè)面的請(qǐng)求如下:

          GET/index.html HTTP/1.1
          HOST:www.kaoyan.net

          ? 上例中使用請(qǐng)求的方法是GET 方法,此方法獲取特定的資源。GET 方法用來(lái)獲

          取名為index.html 的網(wǎng)頁(yè),其他請(qǐng)求方法包括POST、HEAD、DELETE、TRACE及PUT

          方法。例如POST方法用來(lái)提交HTML 表單的內(nèi)容。第二行是頭(header)。 Host 頭規(guī)

          定了在網(wǎng)站上index.html 文件的Internet 地址。此例主機(jī)是www.kaoyan.net

          3.1.3 創(chuàng)建表單的步驟:

          創(chuàng)建表單的步驟如下:

          建立HTML 表單
          使用GET 和POST 方法
          寫B(tài)ean
          傳數(shù)據(jù)到Bean
          Request 對(duì)象
          從Bean 中調(diào)數(shù)據(jù)到JSP 頁(yè)面
          如何運(yùn)行例子

          1. 建立HTML 表單

          ? 一個(gè)HTML 的窗分為三個(gè)部分:<form>標(biāo)簽,輸入方法提交按鈕發(fā)數(shù)據(jù)到服務(wù)器。一般的HTML 頁(yè)面里是這么寫的<form method = get action = someurl>,在其他的頁(yè)面里的action 屬性可能是其他特殊的CGI 程序或者其他能處理數(shù)據(jù)的程序。那么在JSP 里邊是怎么用的呢?如果你想把數(shù)據(jù)發(fā)到Bean 里的話那么你可以省略action 里邊的東西了,直接寫<jsp:useBean>標(biāo)簽或者其他特定的JSP 文件。了接下來(lái)的那些表單和普通的HTML差不多,<input>的方法,然后加一個(gè)提交按鈕,可能還有一個(gè)Reset 按鈕,還得給每一個(gè)input 表單加一個(gè)名字。

          這么寫:

          <input type = “text” name = “username”>

          2. 使用GET 和POST 方法

          ? 用GET 和POST 是從服務(wù)器上請(qǐng)求數(shù)據(jù),POST 是發(fā)送數(shù)據(jù)到服務(wù)器。事實(shí)上GET方法是把數(shù)據(jù)參數(shù)隊(duì)列query string 加到一個(gè)URL上,值和表單是一一對(duì)應(yīng)的。比如說(shuō)name John。在隊(duì)列里,值和表單用一個(gè)&符號(hào)分開,空格用+號(hào)替換,特殊的符號(hào)轉(zhuǎn)換成十六進(jìn)制的代碼。因?yàn)檫@一隊(duì)列在URL 里邊這樣隊(duì)列的參數(shù)就能看得到,可以被記錄下來(lái)或更改。通常GET 方法還限制字符的大小。事實(shí)上POST 方法可以沒(méi)有時(shí)間限制的傳遞數(shù)據(jù)到服務(wù)器,用戶在瀏覽器端是看不到這一過(guò)程的。所以POST 方法比較適合用于發(fā)送一個(gè)保密的比如信用卡號(hào)或者比較大量的數(shù)據(jù)到服務(wù)器。

          3. 寫B(tài)ean

          ? 如果JSP 程序用到了Bean,你就得按照J(rèn)avaBeans API 的說(shuō)明設(shè)計(jì)你的Bean。 記住下面兩個(gè)關(guān)鍵部分。

          ? 如果JSP 程序里用<jsp:getProperty>標(biāo)簽,那你就得在Bean 里邊寫配合的GET方法。

          ? 如果JSP 程序里面用<jsp:setProperty>標(biāo)簽,那你就得在Bean 里邊寫配合的Set 方法。

          ? 設(shè)置參數(shù)到Bean 或者從里邊取參數(shù)將在以后的部分詳細(xì)介紹。

          4. 傳數(shù)據(jù)到Bean

          ? 把HTML 表單的數(shù)據(jù)傳到Bean 里需要兩個(gè)工作:

          ? 用<jsp:useBean>標(biāo)簽創(chuàng)建或者定位到Bean。
          ??在Bean 里面用<jsp:serProperty>設(shè)置屬性值。

          ? 第一步用<jsp:useBean>標(biāo)簽創(chuàng)建或者定位到Bean, 一定要用在<jsp:setProperty>之前,<jsp:useBean>首先按照你指定的名字查找Bean, 如果沒(méi)找到會(huì)給你指定一個(gè)。允許在一個(gè)JSP 文件中創(chuàng)建一個(gè)Bean ,然后在另一個(gè)文件中調(diào)用,這就給了Bean 一個(gè)很廣泛的運(yùn)行空間。

          ? 第二步在Bean 里面用<jsp:setproperty>設(shè)置屬性值,最簡(jiǎn)單的方法是把值定義成與表單名相配合。舉個(gè)例子如果你把表單名定義成username 那么你就在Bean 里定義屬性u(píng)sername ,然后用方法getUsername 和setUsername。

          ? 當(dāng)然也可以定義成不同的名字,只要你不認(rèn)為麻煩。

          5. Request 對(duì)象

          ? 用戶輸入的數(shù)據(jù)用來(lái)存放在Request 對(duì)象里,用javax.servlet.HttpServletRequest 來(lái)執(zhí)行,也可以用其他不同的工具來(lái)執(zhí)行,但他們其實(shí)都是javax.servlet.HttpServletRequest 的子集。

          ? 也可以直接用scriptlet 來(lái)直接訪問(wèn)Request 對(duì)象。Scriptlet 將在以后詳細(xì)的討論

          ? 現(xiàn)在只需要知道他是用腳本語(yǔ)言寫的一段放在<% 和%>之間的代碼就足夠了。在JPS 1.0中必須,用JavaTM 程序語(yǔ)言作為你的腳本語(yǔ)言。

          你經(jīng)常會(huì)用到如下方法處理Request 對(duì)象如下表所示

          方法

          說(shuō)明

          執(zhí)行結(jié)果

          getRequest

          Javax.servlet.jsp.PageContext

          返回當(dāng)前Request對(duì)象

          getParameterNames

          javax.servlet.ServletRequest

          返回當(dāng)前Request對(duì)象參數(shù)名

          getParameterValues

          javax.servlet.ServletRequest

          返回當(dāng)前Request對(duì)象參數(shù)值

          ? 你將會(huì)發(fā)現(xiàn)其他方法包括ServletRequest HttpServletRequest 或者其他任何ServletRequest 的子集。

          ? JSP 引擎經(jīng)常在scenes 之后使用Request 對(duì)象,即使你沒(méi)有明確地在JSP 文件調(diào)用。

          6. 從Bean 中調(diào)數(shù)據(jù)到JSP 頁(yè)面

          ? 一旦用戶的數(shù)據(jù)被傳到Bean,你就想重新得到數(shù)據(jù),然后在JSP 頁(yè)面中顯示出來(lái)。想達(dá)到這一步,,你就得用到<jsp:getProperty>標(biāo)簽傳Bean 名和屬性名。

          <jsp:useBean>, <jsp:setProperty>和<jsp:getProperty>標(biāo)簽必須相配。

          下面舉一個(gè)例子,helloworld.jsphelloworld.java配合,即教材中P21實(shí)例二:

          helloworld.java如下:

          package test;
          public class helloworld
          {
          ? public String name="Hello World!";
          ? public String getHi()
          ? {
          ???? return name;
          ? }
          }

          helloworld.jsp如下:

          <html>
          <head>
          <title>JavaBean 試驗(yàn)</title>
          </head>
          <body>
          <jsp:useBean id = "helloBean" scope="session" class="test.helloworld"/>
          <%=helloBean.getHi()%>
          <hr>
          <%
          ? helloBean.name="Welcom To JSP World!";
          ? out.print(helloBean.getHi());
          %>
          </body>
          </html>

          7. 如何運(yùn)行例子

          ? 把相應(yīng)的文件放到相應(yīng)的路徑即可。hellowworld.jsp放到默認(rèn)的jsp文件存放處。helloworld.java編譯成helloworld.class后放到默認(rèn)的class路徑下建立的test目錄下。輸入“http://127.0.0.1:8080/jspexa/jsp/helloworld.jsp”即可運(yùn)行此例。

          3.2html表單

          3.2.1先例

          ? 先看一個(gè)表單的HTML代碼:

          <html>

          <head>
          <meta http-equiv="Content-Language" content="zh-cn">
          <meta name="GENERATOR" content="Microsoft FrontPage 5.0">
          <meta name="ProgId" content="FrontPage.Editor.Document">
          <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
          <title>輸入域的各種類型</title>
          </head>

          <body>

          <p align="center"><b><font color="#FF0000" size="5">輸入域的各種類型</font></b></p>
          <form method="POST" name="form1" action="test.jsp">
          <table border="1" cellspacing="1" style="border-collapse: collapse" bordercolor="#111111" width="80%" id="AutoNumber1">
          <tr>
          <td width="26%">1<span lang="en-us">.</span>文本框</td>
          <td width="74%"><input type="text" name="T1" size="20"></td>
          </tr>
          <tr>
          <td width="26%">2.口令型文本框</td>
          <td width="74%"><input type="password" name="T2" size="20"></td>
          </tr>
          <tr>
          <td width="26%"><span lang="en-us">3.</span>單選鈕</td>
          <td width="74%"><input type="radio" value="V1" checked name="R1">男&nbsp;&nbsp;&nbsp;
          <input type="radio" name="R1" value="V2">女</td>
          </tr>
          <tr>
          <td width="26%">4.檢查框<span lang="en-us">(</span>多選框<span lang="en-us">)</span></td>
          <td width="74%"><input type="checkbox" name="C1" value="ON">答案<span lang="en-us">A&nbsp;
          <input type="checkbox" name="C2" value="ON"></span>答案<span lang="en-us">B&nbsp;
          <input type="checkbox" name="C3" value="ON"></span>答案<span lang="en-us">C&nbsp;
          <input type="checkbox" name="C4" value="ON"></span>答案<span lang="en-us">D</span></td>
          </tr>
          <tr>
          <td width="26%">5.圖像</td>
          <td width="74%">
          <input type=image name=img1 src="images/wvwelcom.gif" width="76" height="38"></td>
          </tr>
          <tr>
          <td width="26%">6.下拉列表框</td>
          <td width="74%"><select size="1" name="D1">
          <option>優(yōu)秀</option>
          <option>良好</option>
          <option selected>中等</option>
          <option>及格</option>
          <option>不及格</option>
          </select></td>
          </tr>
          <tr>
          <td width="26%">提交按鈕</td>
          <td width="74%"><input type="submit" value="提交" name="B1"></td>
          </tr>
          <tr>
          <td width="26%">重置按鈕</td>
          <td width="74%"><input type="reset" value="重置" name="B2"></td>
          </tr>
          <tr>
          <td width="26%">其它按鈕</td>
          <td width="74%"><input type="button" value="按鈕" name="B3"></td>
          </tr>
          <tr>
          <td width="26%">文本區(qū)</td>
          <td width="74%"><textarea rows="3" name="S1" cols="56"></textarea></td>
          </tr>
          </table>

           </form>

          </body>

          </html>

          執(zhí)行結(jié)果請(qǐng)按此

          3.2.2 表單的標(biāo)記與處理

          表單的標(biāo)記有以下五種類型

          ? <form></form>

          ? <input>

          ? <select></select>

          ? <option>

          ? <textarea></testaea>

          1 Form 標(biāo)記及其用法

          <form>標(biāo)記包含描述文件結(jié)構(gòu)的標(biāo)記同時(shí)還包括一些輸入<input> 標(biāo)記

          <form>標(biāo)記中的參數(shù)包括

          ? ACTION 用于設(shè)定表單的處理方式通常指明一個(gè)處理函數(shù)的URL 地址

          ? METHOD 用于設(shè)定表單的資料傳輸方式如POST 或GET 方式

          ? ENCTYPE 用于設(shè)定以何種編碼方式來(lái)傳送表單的數(shù)據(jù)

          Form 標(biāo)記的用法

          <html>
          <head>
          </head>
          <body>
          <form method="POST" action=" ">
          <table border="0" width="500" cellspacing="0" cellpadding="0"
          align="center">
          <tr>
          <td width="50%">
          <p align="right">用戶名</td>
          <td width="50%">
          <input type="text" name="T1" size="20">
          </td>
          </tr>
          </table>
          </form>
          </body>
          </html>

          2 Input 標(biāo)記及其用法

          使用<input>標(biāo)記可以實(shí)現(xiàn)在表單上輸入信息,每個(gè)輸入域可分配一個(gè)值給予特定名

          稱及變量。Input 標(biāo)記的格式如下:

          <input name="myname" type="mytype">

          其中

          ? Type 的默認(rèn)值是TEXT 也可選擇PASSWORD、CHECKBOX、RADIO、IMAGE、HIDDEN SUBMIT 等參數(shù)值。

          ? Name 用于指定與input 標(biāo)記相應(yīng)表單域的名稱

          ? 可選參數(shù)

          MAXLENGTH 用于限制可以在文本輸入域輸入的字符數(shù)。如果MAXLENGTH 參數(shù)值比SIZE 參數(shù)值大那么域就可以正確翻動(dòng)。字符的預(yù)設(shè)數(shù)字并沒(méi)有什么限制。

          SIZE 指明按照其類型分配給此輸入域的顯示空間大小,預(yù)設(shè)值取決于用戶代理。

          VALUE 域的初始值

          3. Input Type=Password 的用法

          ? 當(dāng)Input 標(biāo)記帶有Type=Password 時(shí),與Text 一樣是一個(gè)文本域,所不同的是在輸入時(shí)它的值是隱藏的,在瀏覽器輸入域中將以*號(hào)隱藏顯示。

          4. Input Type=checkBox 的用法

          當(dāng)Input 標(biāo)記帶有Type=CheckBox 時(shí),可以多次選擇復(fù)選鈕。使用Type=CheckBox的參數(shù)要求如下:

          ? NAME 用于指定與此標(biāo)記或一組標(biāo)記相應(yīng)的表單域的符號(hào)名稱

          ? VALUE 用于表示由此標(biāo)記提供的域值部分

          ? 可選參數(shù)CHECKED 用于指示初始狀態(tài)為ON

          5. Input Type=Radio 的用法

          ? 當(dāng)Input 標(biāo)記帶有Type=Radio 時(shí),只能選擇一個(gè)單選鈕,使用Type=Radio 的參數(shù)要求與CheckBox 一樣Name 和Value 參數(shù)是必須定義的。

          6. Input Type=Image 的用法

          ? 當(dāng)Input 標(biāo)記帶有Type=Image 時(shí),其功能可以指明顯示圖片的來(lái)源,并可以輸入兩個(gè)單域,即從圖片中抽取像素的X 和Y 坐標(biāo),域名稱是附加X(jué) 和Y 的域名稱。TYPE=IMAGE 由SUBMIT 處理。也就是說(shuō),當(dāng)選擇一個(gè)像素后,表單作為一個(gè)整體就被提交。

          ? 使用Type=Image 的參數(shù)要求如下:

          ? Name 用于指定選擇Map 上的點(diǎn),是必須定義的。

          ? SRC 用于指定Map 的圖片名稱,是必須定義的。

          ? ALIGN 是可選參數(shù)。

          Image 的HTML 代碼如下

          <html>

          <head></head>

          <body>

          <p>選擇map 上的一個(gè)點(diǎn)</p>

          <input type=image name=point src="map.gif">

          </body>

          </html>

          7. Input Type=Hidden 的用法

          ? 當(dāng)Input 標(biāo)記帶Type=Hidden 時(shí),表示Input 標(biāo)記是一個(gè)隱藏域,用戶不能與這個(gè)域進(jìn)行交互作用,而是使用Value 參數(shù)值來(lái)定義。

          例如:

          <input type=hidden name=context value="12k3j412k3j41k23">

          8. Input Type=Submit 的用法

          ? 當(dāng)Input 標(biāo)記帶有Type=Submit 時(shí),表示由瀏覽器提交表單的輸入內(nèi)容。通常是一個(gè)命令按鈕,單擊這個(gè)命令按鈕可以將Form 表單輸入的數(shù)據(jù)傳給Web 服務(wù)器。

          ? 使用Type=Submit 的參數(shù)要求如下:

          ? NAME 用于指示該標(biāo)記提供一個(gè)由VALUE 參數(shù)給定其值的表單域.如果NAME參數(shù)不存在則該標(biāo)記不提供表單域。

          ? VALUE 用于指示一個(gè)輸入按鍵標(biāo)記。

          ? Input Type=Submit 有兩種用法:

          ? 向內(nèi)部提交請(qǐng)求的情況

          <input type=submit name=recipient value=internal><br>

          ? 向外部提交請(qǐng)求的情況

          <input type=submit name=recipient value=world>

          9. Input Type=Reset 的用法

          ? 當(dāng)Input 標(biāo)記帶有Type=Reset 時(shí),表示Input 標(biāo)記指示瀏覽器把表單域重置在初始狀

          態(tài),通常是一個(gè)命令按鈕,單擊這個(gè)命令按鈕可以實(shí)現(xiàn)清除表單,并重置初始狀態(tài)。

          例如

          <Input type=Submit> <br>/*提交請(qǐng)求

          <Input type=Reset> /*任何時(shí)候清除表單

          10 Select 標(biāo)記及其用法

          ? Select 標(biāo)記用來(lái)定義表單中的下拉式列表框,<select>和</select>總是成對(duì)出現(xiàn)的。Select標(biāo)記把表單域限制到一個(gè)值的下拉式列表中。Select 的值通過(guò)Option 標(biāo)記來(lái)定義。

          Select 標(biāo)記的格式如下

          <select name="myname" Size= 項(xiàng)目數(shù)>

          其中

          ? Name 指定表單域的名稱

          ? Size 指定可視項(xiàng)目的數(shù)目

          11 Option 標(biāo)記及其用法

          ? 使用Option 標(biāo)記定義表單中下拉式列表框中的項(xiàng)目,Option 標(biāo)記只能在Select 標(biāo)記中使用,Option 標(biāo)記的格式如下:

          <Option Value="值" Selected>菜單選項(xiàng)</Option>

          其中

          ? Value 用來(lái)指示該選項(xiàng)被選定時(shí)返回的值。

          ? Selected 指示該選項(xiàng)在初始狀態(tài)時(shí)被選擇。

          ? 菜單項(xiàng)是指下拉式列表框中定義的內(nèi)容。

          例如

          <option value="中國(guó)科學(xué)院"selected>"中國(guó)科學(xué)院"</option>

          <option value="軟件所" >"軟件所"</option>

          <option value="計(jì)算中心" >"計(jì)算中心"</option>

          ?? 執(zhí)行結(jié)果中國(guó)科學(xué)院為初始狀態(tài)時(shí),被選擇下拉式列表框中的菜單選項(xiàng)為中國(guó)科學(xué)

          院、軟件所、計(jì)算中心。

          11 Textarea 標(biāo)記及其用法

          ? 使用Textarea 標(biāo)記可以定義一個(gè)多行的文本框。當(dāng)文本行超過(guò)定義的區(qū)域時(shí),HTML

          瀏覽器允許用戶根據(jù)需要通過(guò)翻屏的方式突破這些限制進(jìn)行擴(kuò)展。

          Textarea 標(biāo)記的格式如下

          <Textarea Name="名稱" Rows=高度 Cols=寬度>

          其中

          ? Name 用來(lái)指明表單域的名稱

          ? Rows 用字符數(shù)表示顯示文本區(qū)域的可視高度

          ? Cols 用字符數(shù)表示顯示文本區(qū)域的可視寬度

          Textarea 標(biāo)記的用法

          ? 歸納起來(lái)表單元素的特征如下表所示

          表單元
          素名稱

          ?

          TEXT

          一個(gè)單行的文本字段,使用SIZE=屬性可以指定該字段的可見(jiàn)長(zhǎng)度,使用MAXLENGTH屬性可以指定該字段中能夠包含的字符數(shù)的最大數(shù)量

          PASSWORD

          跟TEXT一樣,但是所鍵入的字符不會(huì)回顯到屏幕上,而是以星號(hào)*來(lái)代替所鍵入的字符

          CHECKBOX

          這個(gè)元素代表一個(gè)Boolean布爾值,使用CHECKED屬性來(lái)表示當(dāng)表單第一次顯示時(shí),這個(gè)元素應(yīng)該是預(yù)選中的

          RADIO

          跟復(fù)選框CHECKBOX類似,但是用于一組彼此互相排斥的屬性。當(dāng)用戶單擊組中任何一個(gè)單選按鈕時(shí),組中所有其他按鈕就自動(dòng)地不被選中。通過(guò)給一組按鈕相同的NAME屬性就可以指定這些按鈕為同一組

          SUBMIT

          用戶單擊這個(gè)按鈕時(shí),瀏覽器就會(huì)把表單發(fā)送到表單的動(dòng)作處理程序中,可以通過(guò)給VALUE屬性賦值來(lái)給這個(gè)按鈕一個(gè)submit以外的標(biāo)簽

          RESET

          用戶單擊這個(gè)按鈕時(shí),會(huì)把表單中所有元素的取值都重置為默認(rèn)值。這個(gè)按鈕也有VALUE屬性,可以給按鈕更換標(biāo)簽

          IMAGE

          帶有圖形圖像的發(fā)送按鈕,當(dāng)用戶單擊IMAGE元素時(shí)鼠標(biāo)單擊時(shí)的x和y坐標(biāo)就被發(fā)送到服務(wù)器端程序

          HIDDEN

          一個(gè)隱藏值,對(duì)用戶來(lái)說(shuō)是不可見(jiàn)的,可以用來(lái)指定一個(gè)硬編碼的表單值

          實(shí)例

          按鈕:jspexa/jsp/Button.html , jspexa/jsp/InputButton.html

          檢查框:jspexa/jsp/InputCheckbox.html

          隱藏屬性:jspexa/jsp/InputHidden.html

          圖片屬性:jspexa/jsp/InputImage.html

          密碼屬性:jspexa/jsp/InputPassword.html

          單選鈕屬性:jspexa/jsp/InputRadio.html

          重置屬性:jspexa/jsp/InputReset.html

          SUBMIT 屬性:jspexa/jsp/InputSubmit.html

          TXET 文本屬性:jspexa/jsp/InputText.html

          LABEL 屬性:jspexa/jsp/Label.html

          下拉列表框:jspexa/jsp/Select.html

          TEXTAREA 文本區(qū):jspexa/jsp/Textarea.html

          3.3 3 Servlet與 HTML表單

          ? HTML 文件中用戶對(duì)表單的處理是從提供初始狀態(tài)的域給該文件開始的。對(duì)表單的處理可分為表單提交和表單清除兩部分。

          表單提交

          ?用戶通過(guò)表單提交按鍵或圖形輸入來(lái)提交表單時(shí),則根據(jù)方法ACTION URI 及ENCTYPE 來(lái)處理表單數(shù)據(jù)組。

          ? 如果表單中僅有一個(gè)單行文本輸入域,瀏覽器應(yīng)在此域中接受Enter 作為提交表單的請(qǐng)求。

          (1) 表單URL編碼媒體類型(The Form Url Encoded Media Type)

          ? 表單的默認(rèn)編碼是Application/x-www-form=urlencoded。

          (2) 查詢表單METHOD=GET

          ? 如果表單處理很簡(jiǎn)單,所提交的數(shù)據(jù)很少,并且該數(shù)據(jù)的安全性并不重要,那么采用GET的方法比較好。它可以使你用最簡(jiǎn)單的方式向服務(wù)器傳輸數(shù)據(jù)。但是,URL 編碼可能會(huì)造成URL 非常長(zhǎng)的后果,這就會(huì)導(dǎo)致HTTP 服務(wù)器的一些執(zhí)行歷史記錄出現(xiàn)錯(cuò)誤動(dòng)作。因而一些HTML 表單還是使用METHOD=POST 寫成。

          (3) 表單提交METHOD=POST

          ? POST 方式輸入的數(shù)據(jù)長(zhǎng)度不受限制,并且你在瀏覽器的請(qǐng)求地址內(nèi)也看不到你的輸入。

          表單清除

          ? 表單清除按鈕的Reset 性質(zhì)表示當(dāng)用戶單擊這個(gè)按鈕時(shí)會(huì)把表單中所有元素的取值都重置為默認(rèn)值。這個(gè)按鈕也有VALUE 屬性,可以給按鈕更換標(biāo)簽R。eset 的使用方法如下;

          <input type="reset" name="Submit2" value="表單清除">

          1.URL地址與 Query String

          ? Get方法所收得的變量其實(shí)就是URL的Query String所代表的值,可以有3種方法向服務(wù)器傳送Query String。

          (l)直接在測(cè)覽器的地址欄輸入、其輸入格式為:?key1=value1&key2=value2... ...例如:

          http://localhost:8080/examples/jsp/snp/snoop.jsp?id=10&nickname=girl

          (2)使用 HTML的URL Link方法。在HTML中可以直接在字符串上加入鏈接功能,即通常所說(shuō)的超級(jí)鏈接。以下是一個(gè)URL Link方式的例子:

          <a href="http://localhost:8080/examples/jsp/snp/snoop.jsp?id=10&nickname=dam boo">使用URL Link方式傳遞GET參數(shù)</a>

          ? 如果有可視化的HTML編輯工具(例如 Frontpage)就叮以直接在字符串的屬性欄里修改Link參數(shù)來(lái)設(shè)置。

          (3)使用Form表單。這種方法已經(jīng)進(jìn)行了詳細(xì)的介紹。下面將舉一個(gè)簡(jiǎn)單的例子 form.html來(lái)實(shí)現(xiàn) URL Link與 Form表單這兩種方法。

          文件form.html

          <html>
          <head>
          ?<meta http-equiv="Content-Language" content="zh-cn">
          ?<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
          ?<meta name="ProgId" content="FrontPage.Editor.Document">
          ?<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
          ?<title>請(qǐng)輸入您的昵稱</title>
          </head>
          <body>
          ?<form method="POST" name="form" action="http://localhost:8080/examples/jsp/snoop.jsp">
          <p>
          ?<b><font color="#000080" size="4">請(qǐng)輸入您的昵稱:</font></b><input ?type="text" name="T1" size="20"></p>
          ?<p><input type="submit" value="提交" name="submit1"><input type="reset" value="重置" name="submit2"></p>
          ?<p><font size="4" color="#000080"><b>
          <a href="http://localhost:8080/examples/jsp/snp/snoop.jsp?id=10&nickname=dam boo">
          使用<span lang="en-us">URL Link</span>方式傳遞<span lang="en-us">GET</span>參數(shù)</a></b></font></p>
          ?</form>
          ?<p> </p>
          </body>
          </html>

          本例中單擊“提交”按鈕或是單擊下方的超級(jí)鏈接都會(huì)向?yàn)g覽器傳送URL

          http://localhost:8080/examples/jsp/snp/snoop.jsp?id=10&nickname=dam boo

          其功能與直接在測(cè)覽器地址欄鍵入相同。

          2.Servlet API中與輸入輸出有關(guān)的 API

          ? 在servlet中可以調(diào)用Java的API函數(shù),其中最經(jīng)常使用的就是與輸入輸出有關(guān)的API。以下列舉了這些常用的API函數(shù)。

          ServletRequest

          public java.lang.Object getAttribute(java.lang.String name)

          public java.util.Enumeraion getAttributeNames()

          Public java.lang.String getCharactereucoding()

          public int getContentLength()

          public java.lang.String getContentType()

          public ServletInputStream getInputStream()throws java.io.IOException

          public java.lang.String getParameter(java.lang.Stringname)

          public java.lang.String[] getParameterValues(java.lang.String name)

          public java.lang.String getProtocol()

          public java.lang.String getScheme()

          public java.lang.String getServerName()

          public int getServerPort()

          Public java.io.BufferedReader getReader()throws java.io.IOException

          Public java.lang.String getRemoteAddr()

          Public java.lang.String getRemoteHost()

          Public void setAttribute(java.lang.String key.java.lang.Object o)

          Public java.lang.String getRealPath(java.lang.String path)

          HttPServletRequest

          Public java.lang.String getAuthType()

          public long getDateHeader(java.lang.String name)

          public java.lang.String getHeader(java.lang.String name)

          public java.util.Enumeration getHeaderNames()

          public int getIntHeader(java.lang.String name)

          public java.lang.String getMcthod()

          pubIic java.lang.String getPathInfo()

          public java.lang.String getPathTranslated()

          pubIic java.lang.String getRemoteUser()

          public java.lang.String getServletPath()

          ServletResponse

          pchlic java.lang.String getCharacterEncoding()

          public ServletOutPutStream getOutputStream()throws java.io.IOException

          public java.io.PrintWriter getWriter()throws java.io.IOException

          public void setContentLength(int len)

          HttpServletResponse

          public void setContentType(java.lang.String type)

          public boolean containsHeader(java.lang.String name)

          public void sendError(int sc.java.lang.String msg)throws java.io.IOExcrption
          ????
          public void sendError(int sc)throws java.io.IOExcaption
          ????
          public void sendRedirect(java.lang.String location)throws java.io.IO Excaption
          ????
          public void setDateHeader(java.lang.String name,long date)
          ????
          public void setHeader(java.lang.String name.java.lang.String value)
          ????
          public void setIntHeader(java.lang.String name,int value)

          public void setStatus(int sc)
          ????
          public void setStatos(int sc.java.lang.String sm)

          3.使用Servlet程序處理表單

          ? 以上介紹的是在客戶端的HTML表單提交程序。表單提交以后,在服務(wù)器端的Servlet程序就可以對(duì)上傳數(shù)據(jù)進(jìn)行處理了。例如填人數(shù)據(jù)庫(kù)、查詢、網(wǎng)上購(gòu)物等。以下請(qǐng)看一個(gè)讀取HTML表單的實(shí)例,formgetexmple.html生成一個(gè)提交的表單,formGetExmple Servlet程序在服務(wù)器端進(jìn)行讀取。

          文件formgetexmple.html

          <html>
          <head>
          <title>表單處理實(shí)例</title>
          </head>
          <body>
          <form method="get" action="http://localhost:8080/servlet/jspexa/formGetExample"><div align="center">
          ??? <center>
          ??? <table border="2" cellspacing="1" style="border-collapse: collapse" width="59%" id="AutoNumber1" bordercolorlight="#0000FF" bordercolordark="#00FF00">
          ????? <tr>
          ??????? <td width="21%">昵稱<span lang="en-us">:</span></td>
          ??????? <td width="79%"><input type="text" name="nickname" size="20"></td>
          ????? </tr>
          ????? <tr>
          ??????? <td width="21%">密碼<span lang="en-us">:</span></td>
          ??????? <td width="79%"><input type="password" name="password" size="20"></td>
          ????? </tr>
          ????? <tr>
          ??????? <td width="21%">確認(rèn)密碼<span lang="en-us">:</span></td>
          ??????? <td width="79%"><input type="password" name="password2" size="20"></td>
          ????? </tr>
          ????? <tr>
          ??????? <td width="21%">性別<span lang="en-us">:</span></td>
          ??????? <td width="79%"><input type="radio" value="1" name="gender">男&nbsp;
          ??????? <input type="radio" name="gender" value="2">女
          ??????? <input type="radio" name="gender" value="0" checked>保密</td>
          ????? </tr>
          ????? <tr>
          ??????? <td width="21%">愛(ài)好<span lang="en-us">:</span></td>
          ??????? <td width="79%"><input type="checkbox" name="fond" value="1">旅游&nbsp;
          ??????? <input type="checkbox" name="fond" value="2">體育&nbsp;
          ??????? <input type="checkbox" name="fond" value="3">音樂(lè)&nbsp;
          ??????? <input type="checkbox" name="fond" value="4">攝影</td>
          ????? </tr>
          ????? <tr>
          ??????? <td width="21%">地區(qū)<span lang="en-us">:</span></td>
          ??????? <td width="79%"><select size="1" name="area">
          ??????? <option selected value="1">北京</option>
          ??????? <option value="2">上海</option>
          ??????? <option value="3">重慶</option>
          ??????? <option value="4">天津</option>
          ??????? <option value="5">其它</option>
          ??????? </select></td>
          ????? </tr>
          ????? <tr>
          ??????? <td width="21%">隱藏域<span lang="en-us">:</span></td>
          ??????? <td width="79%"><input type="hidden" name="hidden" value="hidden example"></td>
          ????? </tr>
          ??? </table>
          ??? </center>
          ? </div>
          ? <p align="center"><input type="submit" value="提交" name="submit"><span lang="en-us">&nbsp;
          ? </span><input type="reset" value="重置" name="reset"></p>
          </form>
          </body>
          </html>

          formgetexample.html的作用是生成一個(gè)表單

          文件formGetExample.java
          import java.io.*;
          import java.util.*;
          import javax.servlet.*;
          import javax.servlet.http.*;
          public class formGetExample extends HttpServlet{
          public void doGet(HttpServletRequest request,HttpServletResponse response)
          throws IOException,ServletException
          {
          response.setContentType("text/html");
          PrintWriter out =response.getWriter();
          out.println("<html>");
          out.println("<body bgcolor=\"white\">");
          out.println("<head>");
          out.println("<title>Servlet Get Example </title>");
          out.println("</head>");
          out.println("<body>");
          out.println("<h1> Servlet Get Example</h1>");
          Enumeration enum = request.getParameterNames();
          while(enum.hasMoreElements())
          {
          String key = (String) enum.nextElement();
          String value = request.getParameter(key);
          out.println("<p>");
          out.println(key+"="+value);
          out.println("</p>");
          }
          out.println("</body>");
          out.println("<html>");
          out.close();
          }
          }

          ? 在命令行執(zhí)行javac formGetExample.java,運(yùn)行后將生成一個(gè)formGetExample.class文件。將 formGetExamle.class拷貝到合適的目錄下,用瀏覽器 打開formgetexamle.html文件,單擊確定按鈕后就可以運(yùn)行formGetExmple servlet了。

          ? 使用Get請(qǐng)求讀取表單數(shù)據(jù),調(diào)用的方法是doGet()

          public void doGet(HttpServletRequest request,HttpServletResponse response)
          throws IOException, ServletExcepion

          ? 然后說(shuō)明生成的文檔是text還是html類型,并定義out對(duì)象。

          response.setContentType("text/html");
          PrintWriter out = response.getWriter();

          ? 讀取表單中某個(gè)域"key"的值,使用的是 HttpSerletResponse中的getParameter方法 , public java.lang.String getParameter(java.lang.Stringname) 。也就是說(shuō),如果已知某個(gè)域的name屬性是“nickname”則可以直接使用getParamter(nickname)來(lái)返回該域的值。在不知道域的name屬性情況下,可以使用HttpServletResponse中的getParameterName方法:public java.util.Enumration getParameterNams()。該方法將返回一個(gè) Enumeration型的對(duì)象,例如formGetExmple程序中的enum對(duì)象:

          Enumration enum = request.getParameterName();
          while(enum.hasMoreElements())
          {
          String key = (String) enum.nextElement);
          String value = request.getParameter(key);
          out.ptintln("<P>");
          out.println(key+"="+value);
          out.println("</P>");
          }

          ? 這樣就可以列出所有的Key-Value了。

          3.3 Servlet處理復(fù)雜Form元件

          ? 在formGetExample.java中,一些簡(jiǎn)單的元件例如文本框、密碼框、隱藏域等,這些元件的值可以直接通過(guò)賦值語(yǔ)句“String value=request.getParameter(key);”獲得。但是在單選框(Radio)、復(fù)選框(Checkbox)、列表框等復(fù)雜元件中,就需要進(jìn)一步進(jìn)行編程,來(lái)判斷客戶的輸人內(nèi)容。以下將介紹幾個(gè)處理復(fù)雜Form元件的例子。

          1. 單選框(Radio

          ? 在formGetExmple例子中,性別一欄的代碼是:

          <input type="radio" value="1" name="gender">男&nbsp;
          <input type="radio" name="gender" value="2">女
          <input type="radio" name="gender" value="0" checked>保密

          ? 提交時(shí),返回的值是value,即0、l或者2,而程序需要的是得到用戶的性別信息,所以在Servlet程序中,應(yīng)該改為以下代碼。 String gender = req ucst. getP arameterf' trend er'' ); String valueed'"; if(gender.equals("l")) value=" N "; else iftgender.equals("2")) vaIue="k"; eIse value="#$"; 還有一種簡(jiǎn)單的辦法是直接在HTML表單里修改Vlue屬性。但是在某些情況下 JSWDK不支持中文,這時(shí)候就只能使用以上的辦法了。

          2.復(fù)選框(Checkbox)

          ? 在formGetExmple例子中,愛(ài)好一欄的代碼是。

          <input type="checkbox" name="fond" value="1">旅游&nbsp;
          ??????? <input type="checkbox" name="fond" value="2">體育
          ??????? <input type="checkbox" name="fond" value="3">音樂(lè)
          ??????? <input type="checkbox" name="fond" value="4">攝影

          ?因?yàn)閺?fù)選框允許多種選擇,所以當(dāng)使用request.getParameter()時(shí),系統(tǒng)只會(huì)選中其中的一個(gè)值。在上例中;輸出結(jié)果中只顯示了fond=1。這時(shí)候應(yīng)該使用getParamterValues 方法:public java.lang.String[] getParameterValues(java.lang.String name)。這個(gè)方法的參數(shù)一樣是 HTMLform元件的key值,但是傳回的是一個(gè)字符串的數(shù)組,而不是單一的字符串了。在Servlet程序中,應(yīng)該改為以下代碼。

          String[] fonds = request.getParameterVaues("fond");
          String value="";
          for(int i=0;i<fonds.length;i++
          {
          if(fonds[i].equals("l"))
          value=value+"旅游、";
          else if(fonds[i].equals("2"))
          va1ue=value+"體育、";
          else if(fonds[i].equals("3"))
          value=value+"音樂(lè)、";
          else if(fonds[i].equals("4"))
          valuee=value+"攝影";
          }

          ?在這種情況下,即使在HTML表單設(shè)計(jì)時(shí)就使用了value="旅游"這樣的提交方式; 也要進(jìn)行以上的步驟才能獲得用戶提交的所有信息。

          3 修改后的 formGeffixample Servlet

          ? 其他復(fù)雜元件的處理方法基本上與這兩種相同。以下將formGetExmple.java進(jìn)行了修改,使其可以處理以上介紹的復(fù)雜表單。 以下是修改后的文件 formGetExample.java。

          import java.io.*;
          import java.util.*;
          import javax.servlet.*;
          import javax.servlet.http.*;
          public class formGetExample extends HttpServlet{
          public void doGet(HttpServletRequest request,HttpServletResponse response)
          throws IOException,ServletException
          {
          response.setContentType("text/html");
          PrintWriter out =response.getWriter();
          out.println("<html>");
          out.println("<body bgcolor=\"white\">");
          out.println("<head>");
          out.println("<title>Servlet Get Example </title>");
          out.println("</head>");
          out.println("<body>");
          out.println("<h1> Servlet Get Example</h1>");
          String gender = request.getParamtert("gender");
          String value="";
          if(gender.equals("1"))
          value="男";
          else if(gender.equals("2"))
          value="女";
          else value="保密";
          out.println("性別="+ value);
          out.println("<br>");
          String[] fonds = request.getParameterValues("fond");
          value="";
          for(int i=0;i<fonds.length;i++
          {
          if(fonds[i].equals("l"))
          value=value+"旅游、";
          else if(fonds[i].equals("2"))
          va1ue=value+"體育、";
          else if(fonds[i].equals("3"))
          value=value+"音樂(lè)、";
          else if(fonds[i].equals("4"))
          valuee=value+"攝影";
          }
          out.println("愛(ài)好=" + value );
          out.prinfln("<br>");
          String area = request.getParameter("area");
          value="";
          if(area.equals("l"))
          value="北京";
          else if(area.equals("2"))
          value="上海";
          else if(area.equals("3"))
          value="重慶";
          else if(area.equals("4"))
          value="天津';
          else
          value="其它";
          out.println("地區(qū)="+ value);
          out.println("<br>");
          out.println("</body>");
          out.println("</html>");
          out.close();
          }
          }

          3.4 Servlet獲取環(huán)境變量

          ? 以下的例子使用Servlet來(lái)讀取提交網(wǎng)頁(yè)的CGI環(huán)境變量。

          import java.io.*;
          import java.text.*;
          import java.util.*;
          import javax.servlet.*;
          import javax.servlet.http.*;
          public class cgiGetExample extends HttpServlet{
          public void doGet(HttpServletRequest req,HttpServletResponse res)
          throws IOException,ServletException
          {// 首先設(shè)置頭部
          res.setContentType("text/html");
          // 用write方法返回相應(yīng)數(shù)據(jù)
          PrintWriter out = res.getWriter();
          out.println("<HTML>");
          out.println("<HEAD>");
          out.println("<TITLE>CGI GET EXAMPLE</TITLE>");
          out.println("</HEAD>");
          out.println("<BODY>");
          out.println("<h1>CGI GET EXAMPLE</h1>");
          Enumeration enam=req.getHeaderNames();
          while(enam.hasMoreElements()){
          String name=(String)enam.nextElement();
          String value=req.getHeader(name);
          if((value!=null)&&(!value.equals("")));{
          out.println("<b>"+name+"</b>");
          out.println(":");
          out.println(value);
          out.println("<br>");
          }
          }
          out.println("</body>");
          out.println("</html>");
          out.close();
          }
          }

          4 Servlet與網(wǎng)頁(yè)的結(jié)合

          ? 為了使程序更加具有通用性,網(wǎng)站的編程人員常常需要把servet程序與網(wǎng)頁(yè)的HTML語(yǔ)言結(jié)合起來(lái)。以下將介紹HTML與Servlet之間的相互調(diào)用。

          4.1 HTML中調(diào)用 Servlet程序

          ? 對(duì)網(wǎng)站的編程人員來(lái)說(shuō),經(jīng)常會(huì)需要在網(wǎng)頁(yè)中插人Servlet。首先,許多HTML標(biāo)記可以使用可視化的網(wǎng)頁(yè)上成器,例如Frompage、Dreamwaver來(lái)實(shí)現(xiàn)。如果用Servlet生成HTML則會(huì)非常麻煩,例如:

          <div align="center"><a href="red.j sp" target="_blank"><font color="#FF0000"><font size="6">red<font></b></i></font></a>

          ? 以上語(yǔ)句只是在瀏覽器中顯示一個(gè)紅色的粗體字"red",該字符串以彈出窗口超級(jí)鏈接到red.jsp上。這么長(zhǎng)的HTML語(yǔ)句frontpage中可以用很簡(jiǎn)單的屬性設(shè)置來(lái)實(shí)現(xiàn),但是如果用Servlet來(lái)實(shí)現(xiàn)的話,則是以下語(yǔ)句:

          out.println("<div align=\"center\"><a href=\"red.jsp\" target=\"_blank\"><font color=\"#FF0000\"><font size="\6\">red<font></b></i></font></a>");

          ? 這樣一來(lái),不僅非常麻煩,容易產(chǎn)生錯(cuò)誤,而且同站的美觀也無(wú)法得到保證。另外,網(wǎng)頁(yè)編程人員需要大量的HTML標(biāo)記知識(shí),不能把全部精力用于網(wǎng)頁(yè)編程上。其次,Servlet程序每修改一次就要編譯調(diào)試一遍。當(dāng)編程人員不想修改原有的Servlet程序,只是想修改它的輸出結(jié)構(gòu)時(shí)(例如將數(shù)據(jù)庫(kù)里的資料顯示到用戶端的Servlet程序),完全沒(méi)有必要把整個(gè)Servlet程序重新編譯一遍。以下是在HTML文件中調(diào)用Servler程 序的規(guī)范:

          <html>
          <body>
          <pre>
          <SERVLET CODE="yourservlet">

          <PARAM NAME=youname VALUE="yourvalue">
          ... ...
          </SERVLET>
          </pre>
          </body>
          </html>

          ? <SERVLET CODE="yourservlet">中,Code參數(shù)所指的就是要插入的Servlet的名稱;即呼叫http://locahost/servlet/yourservlet;并將其輸出結(jié)果與HTML文件相結(jié)合。在HTML文件中,還可以在 GET 模式中以URL傳遞參數(shù),就是利用<PARAM NAME=yourname VALUE="yourvalue">來(lái)傳遞,其方法和表單的傳送完全相同。值得一提的是,這個(gè)功能并不在Servlet使用規(guī)范之內(nèi),所以并不是每一個(gè)Servlet引擎或支持Servlet的Web Server就一定會(huì)有這個(gè)功能。

          4.2 在JSP中調(diào)用Servlet程序

          ? 在JSP中,可以利用<jsp:forward page=yourservlet"/>標(biāo)簽重定向到一個(gè)HTML文件,JSP文件,或者是程序段。因此。可以利用<jsp:forward>標(biāo)簽從一個(gè)JSP文件向一個(gè)Servlet 程序傳遞包含用戶請(qǐng)求的 Request對(duì)象。在這種情況下,<jsp:forward>標(biāo)簽以下的代碼將不能執(zhí)行,以轉(zhuǎn)到所需要的Servlet程序。如果想在轉(zhuǎn)移的時(shí)候向目標(biāo)文件傳送參數(shù)和值;可以使用<jsp:param>標(biāo)簽。如果使用了<jsp:param>標(biāo)簽的話,目標(biāo)文件必須是一個(gè)動(dòng)態(tài)的文件,能夠處理參數(shù)。注意,如果你使用了非緩沖輸出的話,那么使用<jsp:forward>時(shí)就要小心;如果在你使用<jsp:forward>之前,jsp文件已經(jīng)有了數(shù)據(jù);那么文件執(zhí)行就會(huì)出錯(cuò)。以下是一個(gè)JSP程序調(diào)用Servlet的例子。

          文件 toservlet.jsp

          <html>
          <head>
          <title> Form JSP to Servlet</title>
          <meta http-equiv="Content-Type" content="text/html;charset=gb2312">
          </head>
          <body bgcolor="#FFFFFF"
          <jsp:forward page="/jspexa/servlet/toJSP"/>
          </body>
          </html>

          ? 當(dāng)在測(cè)覽器中測(cè)覽 toservlet.jsp時(shí);程序就會(huì)被重定向到toJSP.servlet。除了使用<jsp:forward>指令外,還可以使用<jsp:include>來(lái)包含一個(gè)Servlet程序。

          4.3 在Servlet程序中調(diào)用JSP

          ? 在Servlet程序中調(diào)用JSP的方法是:getServletConfig().getServletContext(). getRequestDispatcher("/jspexa/jsp/stj.jsp).forward(request,response);以下是上例中toservlet.jsp調(diào)用的Servlet程序,該程序又重新定向到/jspexa/jsp/stj.jsp,即經(jīng)過(guò)兩次重定向,又轉(zhuǎn)回到JSP程序。

          文件:toJSP.java

          import java.io.*;
          import java.util.*;
          import javax.servlet.*;
          import javax.servlet.http.*;
          public class toJSP extends HttpServlet{
          ? public void doGet(HttpServletRequest request,HttpServletResponse response)
          ? {try{request.setAttribute("comefrom","Servlet");
          ?? getServletConfig().getServletContext().getRequestDispatcher("/jspexa/jsp/stj.jsp").forward(request,response);
          ??? }catch(Exception ex){
          ???? ex.printStackTrace();
          ??????? }
          ? }
          }

          文件 stj.jsp
          <html>
          <body bgcolor="white">
          <h1>
          This page is redir from:
          <% out.println(request.getAttribute("comefrom").toString();%>
          </h1>
          </html>

          把上述文件全部處理好后,運(yùn)行toservlet.jsp,可以看到重新定向的情況。

          5 中文顯示問(wèn)題及其解決辦法

          ? 若在網(wǎng)頁(yè)中中文無(wú)法正常顯示,解決辦法如下:

          1.修改區(qū)域設(shè)置。在控制面板中選擇區(qū)域設(shè)置,將中文改為英語(yǔ)(美國(guó)),一切就會(huì)正常。如果還不正常,可重新啟動(dòng)計(jì)算機(jī)。

          2.在JSP頁(yè)面中加入一條語(yǔ)句:
          <%@page contentType="text/html;charset=gb2312"%>
          (此舉在Tomcat中可能不起作用。)

          3.在編譯servlet時(shí)加入代碼選項(xiàng):
          javac -encoding iso8859-1 文件名.java

          posted on 2006-11-15 20:12 lbfeng 閱讀(2781) 評(píng)論(0)  編輯  收藏 所屬分類: JSP&Servlet技術(shù)
          主站蜘蛛池模板: 中宁县| 鱼台县| 阿荣旗| 宁明县| 德昌县| 玉屏| 镇赉县| 唐山市| 西丰县| 呼伦贝尔市| 呼和浩特市| 子长县| 奇台县| 邯郸市| 元阳县| 德州市| 衢州市| 巍山| 德江县| 苏尼特左旗| 关岭| 金秀| 尚志市| 区。| 顺义区| 启东市| 仲巴县| 望江县| 惠水县| 泾源县| 安塞县| 阿图什市| 吕梁市| 建德市| 南召县| 上思县| 邛崃市| 铜梁县| 丰顺县| 龙游县| 涿州市|