<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Edzy_Java

      BlogJava :: 首頁 ::  ::  ::  :: 管理 ::
      58 隨筆 :: 12 文章 :: 11 評論 :: 0 Trackbacks

    1 Java Servlet簡介

    ? Java Servlet是J S P技術的基礎,而且大型的We b應用程序的開發需要Java Servlet和J S P配合才能完成,這里簡單介紹S e r v l e t的相關知識,S e r v l e t的開發將在其它章節講述。

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

    ? 但Java Servlet也不是沒有缺點,和傳統的C G I、I S A P I、N S A P I方式相同,Java Servlet是利用輸出H T M L語句來實現動態網頁的,如果用Java Servlet來開發整個網站,動態部分和靜態頁面的整合過程簡直就是一場惡夢。這就是為什么S U N還要推出Java Server Pages的原因。

    1.1 JSPServlet

    ? Servlet (服務器小程序)是一個與協議無關的跨平臺的服務器組件。如同APPlet(小程序)被集成到web測覽器中一樣,它被集成到服務器中,可以實現網絡遠程動態加載。 最初,主要是把Servlet集成到支持HTTP協議的Web服務器上,但是隨著它的不斷改進 現在巳經集成到實現Java服務器API的任何服務上了。同時,Servlet也是實現智能代理的第一步。JSP主要關注于HTML(或者XML)與Java代碼的結合,以及加入其中的JSP 標記。如果一個支持JSP的服務器遇到一個JSP頁面,它首先查看該頁面是否被編譯成為一個Servlet。由此可見,JSP首先被編譯成Servlet,即被轉變為純Java 然后被裝載到服務器執行。當然,這一過程根據不同的JSP引擎而略有不同。下面是Servlet的一些應用范圍:

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

    (2)允許人們之間的合作。一個Servlet能并發處理多個請求,人們可以使用在諸如在線會議這樣的同步請求支持系統。

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

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

    1.2 Java Servlet的優點

    ? Java Servlets比傳統的CGI或其他CGI類似替代技術來說,只有工作效率更管使用更方便、功能更強大、更小巧也更便宜等優點。下面將具體介紹這些優點。

    1.效率高

    ? 傳統CGI對每一個HTTP請求都要產生一個新的進程。即使某個CGI程序是一個執行非常快的操作,打開進程的時間也占用了大部分執行時間。而對Java Servlets來說,在 Java虛擬機上每一個請求由一個""Java線程(thread)響應,而不是一個"大"操作系統進程。類似地,傳統CGI如果對同一個CGI程序有N個同時請求,這個CGI程序的代碼將被導人內存N次。Java Servlets產生N個線程 但只有一個Java Servlets Class的Copy。同時Java Servlets比CGI有更多的優化選擇,像預先計算、打開數據庫連接等。

    2.使用方便

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

    3.功能強大

    ?Java Servlets可以很容易地實現對CGI來說不可能或很困難的事務。如Java Servlets 能直接和服務器進行通信,而CGI不能。

    4.共享數據

    ? Java Servets之間能共享數據很容易實現數據庫連接池。它能方便地實現管理Request 請求,簡化Session和獲取前一頁面信息的操作。而在CGI之間通信則很差。由于每個CGI 程序的調用都開始一個新的進程;調用間通信通常要通過文件進行,因而相當緩慢。同一臺服務器上的不同CGI程序之間的通信也相當麻煩。

    5.調用時間短

    ? CGI程序是作為單獨過程運行的,通常調用時間較長。這個進程在每次調用的時候都要發生,而在使用解釋器的時候調用時間會更長。與此相比,內存中的Servlet可以非常迅速地加載。

    6.安全

    ? 有些CGI版本具有明顯的安全弱點。即使是使用最新的標準利PERL等語言,系統也沒有基本安全框架,要靠一組事實上的規則。而Java定義有完整的安全機制,包括SSL、CA認證和安全政策等規范。

    7.小巧

    ? Java Servlets使用Java編寫,遵循標準API。它能直接或借助插件在幾乎所有Web 服務器上運行。

    8. 價格低

    ? 現在有很多都是免費軟件或者共享軟件。

    1.3 Servlet的結構

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

    ? 當一個servlet接收來自客戶端的調用請求時,它接收兩個對象類,一個是 ServletRequest,另外一個是ServletResPonse。ServletRequest類概括從客戶端到服務器之間的聯系,而ServletResPonse類概括從Servlet返回客戶端的聯系。

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

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

    ? 上面有關類和接口的描述構成了一個基本的Servlet框架。HTTP Servlet有一些附加的可以提供 Servlet-tracking capabilities的方法。Servlet編寫者可以用這些API在有他人操作時維護Servlet與客戶端之間的狀態。Servlet都是由HttpServlet繼承下來的,其基本結構如下面的代碼所示:

    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)
    ?? //
    和表單提交的數據
    ?? //"response"返回輸出的內容
    ????? PrintWrite out=response.getwriter();
    ?? //
    "Out"向例覽器寫內容。
    ? }
    }

    1.4 Java Servlet接口

    ?Servlet從javax包的httpservlet類擴展,在Httpservlet中加入了一些附加的方法,這些方法可以被協助處理HTTP基本請求的Httpservlet類中的方法Service自動調用。這些方法有:

    1.doGet用來處理HTTP的Get請求

    ? 這個Get請求僅僅允許客戶從HTTP Server上“取得”(get)資源。重載此方法的用戶自動允許支持方法Head。這個Get請求被認為是安全的,沒有任何的副面影響,對用戶來說是很可靠的,比如大多數的正規查詢都沒有副作用。如果想要改變存儲數據的請求必須用其他的HTTP方法。這要求方法也必須是安全的操作。方法doGet的默認執行將返回一個 HTTP的BAD_REQUEST錯誤。

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

    2.doPost用來處理HTTP的Post請求

    這個Post請求包含了在必須通過此Servlet執行的請求中的數據。由于它不能立即取得資源 故對于那些涉及到安全性的用戶來說,通過Post請求操作會有一些副作用。

    ? 方法doPost的默認執行將返回一個HTTP的BAD_REQUEST錯誤。當編寫Servlet時,為了支持Post操作必須在于類HttpServlet中執行此方法。

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

    3 doPut用來處理HTTP的Put請求

    ? 此Put請求模擬通過FTP發送一個文件。對于那些涉及到安全性的用戶來說,通過Put請求操作也會有一些副作用。

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

    4.doDelete用來處理HTTP的Delete請求

    ? 此方法允許客戶端請求一個從Server移出的URL。對于那些涉及到安全性的用戶來說,通過Delete請求操作會有一些副作用。

    ? 方法 doDelete的默認執行將返回一個HTTP的.BAD_REQUEST錯誤。當編寫Servlet時,為支持 Delete請求,必須在子類 HttpServlet中執行此方法。

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

    5. doHead用來處理 HTTP的 Head請求

    ? 默認地,它會在無條件的Get請求執行時期中運行,但不返回任何數據到客戶端,只返回包含內容信息的長度的Header。由于用到Get請求,此方法應該是很安全的(沒有副作用),也是可重復使用的。此方法的默認執行自動地處理了HTTP的Head請求,并且不需要通過一個子類執行。

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

    6. doOptions用來處理HTTP的Options請求

    ? 此方法自動決定支持什么HTTP方法。比如說,如果一個Servlet的作者創建HttPServlet 的子類并重載方法doGet,然后方法doOption會返回下面的header:

    ? Allow:GET,HEAD,TRACE,OPTIONS

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

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

    7.doTrace用來處理HTTP的Trace請求

    ? 此方法的默認執行產生一個包含所有在Trace請求中的header信息的應答。在開發Servlet時,多數情況下需要重載此方法。

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

    ? 在開發以HTTP為基礎的servlet中,方法doGet和方法doPost是最重要的。

    1.5 Servlet的生命周期

    ? Servet程序可以說是在服務器端運行的Applet,甚至比Applet更為簡單,因為Servlet 不需要考慮圖形界面的應用。與Applet一樣 Servlet也有一個生命周期。Servet的生命周期是當服務器裝載運行Servlets,接收來自客戶端的多個請求并且返回數據給客戶端。然后再刪除Servlet。

    ? 詳細描述如下:

    1. 初始化時期

    ? 當一個服務器裝載Servlet時,它運行Servlet的init()方法。

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

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

    2. Servet的執行時期

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

    ...
    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();
    ...

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

    3. servet結束時期

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

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

    1.6 使用Servlets的兩種模式

    ? 當JSP成為開發動態網站的主要技術時,為何在JSP技術中不強調Servets呢?因為Servlets的應用是沒有問題的,它們非常適于服務器端的處理和編程,并且會長期保持現狀。從結構上說,可以將JSP看作是Servlet的一個高層的抽象實現。特別是在servlet 2.2 API下。但是用戶仍然不能無拘束地使用Servlet.因為它們并不適合每一個人,例如頁面設計者可以方便地使用HTML或者XML具開發JSP頁面,但SerVet卻更適合于后端開發者使用,他們的工具是IDE--一個需要更多編程訓練的開發領域。當發布Servlet時,每個開發者必須小心地確定在頁面表現和頁面邏輯之間沒有緊密的關聯出現。用戶可以使用第三方HTML包裝工具,如htmlkona來混合HTML和servlet代碼。即使如此,這點靈活性還不足以讓用戶自由地改變風格本身。例如,如果希望從html改變到dhtml則需要小心測試包裝本身,以確保新的格式可以正確使用。在最壞的情況下,包裝不可用,那就需要應變馬來表現動態內容。所以,需要一種新的解決方案--混合JSP和Servlets的使用。

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

    ? 在模式1中,JSP頁面獨自響應請求并將處理結果返回客戶。這里仍然有表現和內容的分離,因為所有的數據依靠Beans來處理。盡管模式1可以很好的滿足小型應用的需要,但卻不能滿足大型應用的要求。大量使用模式1,常常會導致頁面被嵌人大量的Script或者Java代碼。特別是當需要處理的商業邏輯很復雜時 情況會變得嚴重。也許對于Java 程序員來說,這不算大的問題。但如果開發者是前端界面設計人員——在大型項目中, 這很常見,則代碼的開發和維護將出現困難。在任何項目中,這樣的模式多少總會導致定義不清的響應和項目管理的困難。

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

    ? 使用模式2,JSP和Servlet可以在功能上最大限度的分開。正確地使用模式2,產生一個中心化的控制Servlet,并且只完成顯示的JSP頁面。另一方面,模式2的實現很復雜。因此,在簡單的應用中,可以考慮使用模式l。

    2 創建Servlet程序

    ? Servlet程序使用的語言為Java語言,保存時需要以“*.java”為擴展名。在運行Servlet程序之前,必須對其進行編譯。以下將詳細介紹如何使用Java編譯器對Servlet進行編譯以及如何在JSP程序中加入Servlet程序。

    2.1 如何運行Servlet程序

    ? Java Servlets不像JSP那樣,在第一次訪問時服務器自動編譯,它需要手動編譯。在JDK環境下。可以用命令行程序“javac.exe 編譯。編譯時使用javac命令:

    javac<選項><源文件>

    ?包括下面選項:

    -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

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

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

    ? 其中,C:\jspstudy\tomcat\是各用戶安裝tomcat的目錄,tomcat預設安裝的情況來看,上面的目錄包含的內容如圖3-2所示。凡是Servlet的程序編譯成class文件以后,只要放在這個目錄下,就可以通過URL來取得它。Tomcat的主要配置文件為server.xml,請詳細查看該文件。

    ? 關于Tomcat的配置請參看“Tomcat全攻略”。

    2.2 第一個Servlet程序

    ? 為了更清楚地理解Servlets是如何工作的,下面來詳細地看一個Servlet示例。程序 Hellow.java簡單向客戶端輸出信息。

    文件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”。如果沒有任何提示的話就是運行通過了。執行后會在同一個目錄里生成一個 Hellow.lass文件,為了在瀏覽器里執行Hellow Servlet需要把該class文件放在Tomcat安裝目錄\webapps\ROOT\WEB-INF\classes\目錄下。在測覽器中用httP://localhost:8080/servlet/hellow就可以執行 Hellow servlet了 執行結果見演示或教材圖3-3。如果編譯不通過,請注意Java程序的大小寫問題。如果不是語法錯誤的話,一般就是因為找不到相應的環境變量。如果是這種錯誤,可以在操作系統的環境變量CLASSPATH 中加人教材36頁上半部分的代碼。注意,可以把這些文件集中放到一個文件夾下,以免太分散。

    3 Servlet處理表單提交

    3.1 表單的基本概念

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

    3.1.1 什么是HTML 表單

    ? 在Web 上獲取用戶的信息,大多數情況下都是通過表單來實現的。比如說輸入消費者的姓名、地址,或者輸入一個詞來使用搜索引擎查找,或者從來訪者處收集數據提供參考等等。

    1. HTML 表單的數據流

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

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

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

    3.1.2 HTML 表單的運行原理

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

    ? 在瀏覽器從服務器獲取頁面的過程中,瀏覽器在網站上打開了一個對Internet 服務器的連接并發出請求服務器收到請求后給予回應所以HTTP 協議又被稱為請求和響應協議。

    ? 所有的瀏覽器和服務器間的通信都發生在離散的“請求──響應”對中瀏覽器必須發出請求才開始通信,服務器角色完全是被動的,它必須在被請求后起作用。

    ? 一個典型請求通常包含許多頭。頭提供了關于消息內容的附加信息以及請求的來源。其中有些頭是標準的,其他的是有關特定瀏覽器的。

    ? 一個請求還包含信息體。例如,若請求用POST方法而不是GET方法,信息體可以包含HTML 表單的內容。在HTML 表單上單擊submit 鍵時,該表單使用ACTION = “POST”特征,輸入表單的內容都被發送到服務器上。該表單的內容就由POST 方法在請求的信息體中發送。

    ? 服務器收到請求時返回HTTP 響應。每個響應都由狀態行開始可以包含幾個頭及可能的信息體。

    對頁面的請求如下:

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

    ? 上例中使用請求的方法是GET 方法,此方法獲取特定的資源。GET 方法用來獲

    取名為index.html 的網頁,其他請求方法包括POST、HEAD、DELETE、TRACE及PUT

    方法。例如POST方法用來提交HTML 表單的內容。第二行是頭(header)。 Host 頭規

    定了在網站上index.html 文件的Internet 地址。此例主機是www.kaoyan.net

    3.1.3 創建表單的步驟:

    創建表單的步驟如下:

    建立HTML 表單
    使用GET 和POST 方法
    寫Bean
    傳數據到Bean
    Request 對象
    從Bean 中調數據到JSP 頁面
    如何運行例子

    1. 建立HTML 表單

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

    這么寫:

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

    2. 使用GET 和POST 方法

    ? 用GET 和POST 是從服務器上請求數據,POST 是發送數據到服務器。事實上GET方法是把數據參數隊列query string 加到一個URL上,值和表單是一一對應的。比如說name John。在隊列里,值和表單用一個&符號分開,空格用+號替換,特殊的符號轉換成十六進制的代碼。因為這一隊列在URL 里邊這樣隊列的參數就能看得到,可以被記錄下來或更改。通常GET 方法還限制字符的大小。事實上POST 方法可以沒有時間限制的傳遞數據到服務器,用戶在瀏覽器端是看不到這一過程的。所以POST 方法比較適合用于發送一個保密的比如信用卡號或者比較大量的數據到服務器。

    3. 寫Bean

    ? 如果JSP 程序用到了Bean,你就得按照JavaBeans API 的說明設計你的Bean。 記住下面兩個關鍵部分。

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

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

    ? 設置參數到Bean 或者從里邊取參數將在以后的部分詳細介紹。

    4. 傳數據到Bean

    ? 把HTML 表單的數據傳到Bean 里需要兩個工作:

    ? 用<jsp:useBean>標簽創建或者定位到Bean。
    ??在Bean 里面用<jsp:serProperty>設置屬性值。

    ? 第一步用<jsp:useBean>標簽創建或者定位到Bean, 一定要用在<jsp:setProperty>之前,<jsp:useBean>首先按照你指定的名字查找Bean, 如果沒找到會給你指定一個。允許在一個JSP 文件中創建一個Bean ,然后在另一個文件中調用,這就給了Bean 一個很廣泛的運行空間。

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

    ? 當然也可以定義成不同的名字,只要你不認為麻煩。

    5. Request 對象

    ? 用戶輸入的數據用來存放在Request 對象里,用javax.servlet.HttpServletRequest 來執行,也可以用其他不同的工具來執行,但他們其實都是javax.servlet.HttpServletRequest 的子集。

    ? 也可以直接用scriptlet 來直接訪問Request 對象。Scriptlet 將在以后詳細的討論

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

    你經常會用到如下方法處理Request 對象如下表所示

    方法

    說明

    執行結果

    getRequest

    Javax.servlet.jsp.PageContext

    返回當前Request對象

    getParameterNames

    javax.servlet.ServletRequest

    返回當前Request對象參數名

    getParameterValues

    javax.servlet.ServletRequest

    返回當前Request對象參數值

    ? 你將會發現其他方法包括ServletRequest HttpServletRequest 或者其他任何ServletRequest 的子集。

    ? JSP 引擎經常在scenes 之后使用Request 對象,即使你沒有明確地在JSP 文件調用。

    6. 從Bean 中調數據到JSP 頁面

    ? 一旦用戶的數據被傳到Bean,你就想重新得到數據,然后在JSP 頁面中顯示出來。想達到這一步,,你就得用到<jsp:getProperty>標簽傳Bean 名和屬性名。

    <jsp:useBean>, <jsp:setProperty>和<jsp:getProperty>標簽必須相配。

    下面舉一個例子,helloworld.jsphelloworld.java配合,即教材中P21實例二:

    helloworld.java如下:

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

    helloworld.jsp如下:

    <html>
    <head>
    <title>JavaBean 試驗</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. 如何運行例子

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

    3.2html表單

    3.2.1先例

    ? 先看一個表單的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>優秀</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%">文本區</td>
    <td width="74%"><textarea rows="3" name="S1" cols="56"></textarea></td>
    </tr>
    </table>

     </form>

    </body>

    </html>

    執行結果請按此

    3.2.2 表單的標記與處理

    表單的標記有以下五種類型

    ? <form></form>

    ? <input>

    ? <select></select>

    ? <option>

    ? <textarea></testaea>

    1 Form 標記及其用法

    <form>標記包含描述文件結構的標記同時還包括一些輸入<input> 標記

    <form>標記中的參數包括

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

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

    ? ENCTYPE 用于設定以何種編碼方式來傳送表單的數據

    Form 標記的用法

    <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 標記及其用法

    使用<input>標記可以實現在表單上輸入信息,每個輸入域可分配一個值給予特定名

    稱及變量。Input 標記的格式如下:

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

    其中

    ? Type 的默認值是TEXT 也可選擇PASSWORD、CHECKBOX、RADIO、IMAGE、HIDDEN SUBMIT 等參數值。

    ? Name 用于指定與input 標記相應表單域的名稱

    ? 可選參數

    MAXLENGTH 用于限制可以在文本輸入域輸入的字符數。如果MAXLENGTH 參數值比SIZE 參數值大那么域就可以正確翻動。字符的預設數字并沒有什么限制。

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

    VALUE 域的初始值

    3. Input Type=Password 的用法

    ? 當Input 標記帶有Type=Password 時,與Text 一樣是一個文本域,所不同的是在輸入時它的值是隱藏的,在瀏覽器輸入域中將以*號隱藏顯示。

    4. Input Type=checkBox 的用法

    當Input 標記帶有Type=CheckBox 時,可以多次選擇復選鈕。使用Type=CheckBox的參數要求如下:

    ? NAME 用于指定與此標記或一組標記相應的表單域的符號名稱

    ? VALUE 用于表示由此標記提供的域值部分

    ? 可選參數CHECKED 用于指示初始狀態為ON

    5. Input Type=Radio 的用法

    ? 當Input 標記帶有Type=Radio 時,只能選擇一個單選鈕,使用Type=Radio 的參數要求與CheckBox 一樣Name 和Value 參數是必須定義的。

    6. Input Type=Image 的用法

    ? 當Input 標記帶有Type=Image 時,其功能可以指明顯示圖片的來源,并可以輸入兩個單域,即從圖片中抽取像素的X 和Y 坐標,域名稱是附加X 和Y 的域名稱。TYPE=IMAGE 由SUBMIT 處理。也就是說,當選擇一個像素后,表單作為一個整體就被提交。

    ? 使用Type=Image 的參數要求如下:

    ? Name 用于指定選擇Map 上的點,是必須定義的。

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

    ? ALIGN 是可選參數。

    Image 的HTML 代碼如下

    <html>

    <head></head>

    <body>

    <p>選擇map 上的一個點</p>

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

    </body>

    </html>

    7. Input Type=Hidden 的用法

    ? 當Input 標記帶Type=Hidden 時,表示Input 標記是一個隱藏域,用戶不能與這個域進行交互作用,而是使用Value 參數值來定義。

    例如:

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

    8. Input Type=Submit 的用法

    ? 當Input 標記帶有Type=Submit 時,表示由瀏覽器提交表單的輸入內容。通常是一個命令按鈕,單擊這個命令按鈕可以將Form 表單輸入的數據傳給Web 服務器。

    ? 使用Type=Submit 的參數要求如下:

    ? NAME 用于指示該標記提供一個由VALUE 參數給定其值的表單域.如果NAME參數不存在則該標記不提供表單域。

    ? VALUE 用于指示一個輸入按鍵標記。

    ? Input Type=Submit 有兩種用法:

    ? 向內部提交請求的情況

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

    ? 向外部提交請求的情況

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

    9. Input Type=Reset 的用法

    ? 當Input 標記帶有Type=Reset 時,表示Input 標記指示瀏覽器把表單域重置在初始狀

    態,通常是一個命令按鈕,單擊這個命令按鈕可以實現清除表單,并重置初始狀態。

    例如

    <Input type=Submit> <br>/*提交請求

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

    10 Select 標記及其用法

    ? Select 標記用來定義表單中的下拉式列表框,<select>和</select>總是成對出現的。Select標記把表單域限制到一個值的下拉式列表中。Select 的值通過Option 標記來定義。

    Select 標記的格式如下

    <select name="myname" Size= 項目數>

    其中

    ? Name 指定表單域的名稱

    ? Size 指定可視項目的數目

    11 Option 標記及其用法

    ? 使用Option 標記定義表單中下拉式列表框中的項目,Option 標記只能在Select 標記中使用,Option 標記的格式如下:

    <Option Value="值" Selected>菜單選項</Option>

    其中

    ? Value 用來指示該選項被選定時返回的值。

    ? Selected 指示該選項在初始狀態時被選擇。

    ? 菜單項是指下拉式列表框中定義的內容。

    例如

    <option value="中國科學院"selected>"中國科學院"</option>

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

    <option value="計算中心" >"計算中心"</option>

    ?? 執行結果中國科學院為初始狀態時,被選擇下拉式列表框中的菜單選項為中國科學

    院、軟件所、計算中心。

    11 Textarea 標記及其用法

    ? 使用Textarea 標記可以定義一個多行的文本框。當文本行超過定義的區域時,HTML

    瀏覽器允許用戶根據需要通過翻屏的方式突破這些限制進行擴展。

    Textarea 標記的格式如下

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

    其中

    ? Name 用來指明表單域的名稱

    ? Rows 用字符數表示顯示文本區域的可視高度

    ? Cols 用字符數表示顯示文本區域的可視寬度

    Textarea 標記的用法

    ? 歸納起來表單元素的特征如下表所示

    表單元
    素名稱

    ?

    TEXT

    一個單行的文本字段,使用SIZE=屬性可以指定該字段的可見長度,使用MAXLENGTH屬性可以指定該字段中能夠包含的字符數的最大數量

    PASSWORD

    跟TEXT一樣,但是所鍵入的字符不會回顯到屏幕上,而是以星號*來代替所鍵入的字符

    CHECKBOX

    這個元素代表一個Boolean布爾值,使用CHECKED屬性來表示當表單第一次顯示時,這個元素應該是預選中的

    RADIO

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

    SUBMIT

    用戶單擊這個按鈕時,瀏覽器就會把表單發送到表單的動作處理程序中,可以通過給VALUE屬性賦值來給這個按鈕一個submit以外的標簽

    RESET

    用戶單擊這個按鈕時,會把表單中所有元素的取值都重置為默認值。這個按鈕也有VALUE屬性,可以給按鈕更換標簽

    IMAGE

    帶有圖形圖像的發送按鈕,當用戶單擊IMAGE元素時鼠標單擊時的x和y坐標就被發送到服務器端程序

    HIDDEN

    一個隱藏值,對用戶來說是不可見的,可以用來指定一個硬編碼的表單值

    實例

    按鈕: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 文本區:jspexa/jsp/Textarea.html

    3.3 3 Servlet與 HTML表單

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

    表單提交

    ?用戶通過表單提交按鍵或圖形輸入來提交表單時,則根據方法ACTION URI 及ENCTYPE 來處理表單數據組。

    ? 如果表單中僅有一個單行文本輸入域,瀏覽器應在此域中接受Enter 作為提交表單的請求。

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

    ? 表單的默認編碼是Application/x-www-form=urlencoded。

    (2) 查詢表單METHOD=GET

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

    (3) 表單提交METHOD=POST

    ? POST 方式輸入的數據長度不受限制,并且你在瀏覽器的請求地址內也看不到你的輸入。

    表單清除

    ? 表單清除按鈕的Reset 性質表示當用戶單擊這個按鈕時會把表單中所有元素的取值都重置為默認值。這個按鈕也有VALUE 屬性,可以給按鈕更換標簽R。eset 的使用方法如下;

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

    1.URL地址與 Query String

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

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

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

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

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

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

    (3)使用Form表單。這種方法已經進行了詳細的介紹。下面將舉一個簡單的例子 form.html來實現 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>請輸入您的昵稱</title>
    </head>
    <body>
    ?<form method="POST" name="form" action="http://localhost:8080/examples/jsp/snoop.jsp">
    <p>
    ?<b><font color="#000080" size="4">請輸入您的昵稱:</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>參數</a></b></font></p>
    ?</form>
    ?<p> </p>
    </body>
    </html>

    本例中單擊“提交”按鈕或是單擊下方的超級鏈接都會向瀏覽器傳送URL

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

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

    2.Servlet API中與輸入輸出有關的 API

    ? 在servlet中可以調用Java的API函數,其中最經常使用的就是與輸入輸出有關的API。以下列舉了這些常用的API函數。

    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表單提交程序。表單提交以后,在服務器端的Servlet程序就可以對上傳數據進行處理了。例如填人數據庫、查詢、網上購物等。以下請看一個讀取HTML表單的實例,formgetexmple.html生成一個提交的表單,formGetExmple Servlet程序在服務器端進行讀取。

    文件formgetexmple.html

    <html>
    <head>
    <title>表單處理實例</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%">確認密碼<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%">愛好<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">音樂&nbsp;
    ??????? <input type="checkbox" name="fond" value="4">攝影</td>
    ????? </tr>
    ????? <tr>
    ??????? <td width="21%">地區<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的作用是生成一個表單

    文件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();
    }
    }

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

    ? 使用Get請求讀取表單數據,調用的方法是doGet()

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

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

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

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

    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處理復雜Form元件

    ? 在formGetExample.java中,一些簡單的元件例如文本框、密碼框、隱藏域等,這些元件的值可以直接通過賦值語句“String value=request.getParameter(key);”獲得。但是在單選框(Radio)、復選框(Checkbox)、列表框等復雜元件中,就需要進一步進行編程,來判斷客戶的輸人內容。以下將介紹幾個處理復雜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>保密

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

    2.復選框(Checkbox)

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

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

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

    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+"音樂、";
    else if(fonds[i].equals("4"))
    valuee=value+"攝影";
    }

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

    3 修改后的 formGeffixample Servlet

    ? 其他復雜元件的處理方法基本上與這兩種相同。以下將formGetExmple.java進行了修改,使其可以處理以上介紹的復雜表單。 以下是修改后的文件 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+"音樂、";
    else if(fonds[i].equals("4"))
    valuee=value+"攝影";
    }
    out.println("愛好=" + 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("地區="+ value);
    out.println("<br>");
    out.println("</body>");
    out.println("</html>");
    out.close();
    }
    }

    3.4 Servlet獲取環境變量

    ? 以下的例子使用Servlet來讀取提交網頁的CGI環境變量。

    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
    {// 首先設置頭部
    res.setContentType("text/html");
    // 用write方法返回相應數據
    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與網頁的結合

    ? 為了使程序更加具有通用性,網站的編程人員常常需要把servet程序與網頁的HTML語言結合起來。以下將介紹HTML與Servlet之間的相互調用。

    4.1 HTML中調用 Servlet程序

    ? 對網站的編程人員來說,經常會需要在網頁中插人Servlet。首先,許多HTML標記可以使用可視化的網頁上成器,例如Frompage、Dreamwaver來實現。如果用Servlet生成HTML則會非常麻煩,例如:

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

    ? 以上語句只是在瀏覽器中顯示一個紅色的粗體字"red",該字符串以彈出窗口超級鏈接到red.jsp上。這么長的HTML語句frontpage中可以用很簡單的屬性設置來實現,但是如果用Servlet來實現的話,則是以下語句:

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

    ? 這樣一來,不僅非常麻煩,容易產生錯誤,而且同站的美觀也無法得到保證。另外,網頁編程人員需要大量的HTML標記知識,不能把全部精力用于網頁編程上。其次,Servlet程序每修改一次就要編譯調試一遍。當編程人員不想修改原有的Servlet程序,只是想修改它的輸出結構時(例如將數據庫里的資料顯示到用戶端的Servlet程序),完全沒有必要把整個Servlet程序重新編譯一遍。以下是在HTML文件中調用Servler程 序的規范:

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

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

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

    4.2 在JSP中調用Servlet程序

    ? 在JSP中,可以利用<jsp:forward page=yourservlet"/>標簽重定向到一個HTML文件,JSP文件,或者是程序段。因此。可以利用<jsp:forward>標簽從一個JSP文件向一個Servlet 程序傳遞包含用戶請求的 Request對象。在這種情況下,<jsp:forward>標簽以下的代碼將不能執行,以轉到所需要的Servlet程序。如果想在轉移的時候向目標文件傳送參數和值;可以使用<jsp:param>標簽。如果使用了<jsp:param>標簽的話,目標文件必須是一個動態的文件,能夠處理參數。注意,如果你使用了非緩沖輸出的話,那么使用<jsp:forward>時就要小心;如果在你使用<jsp:forward>之前,jsp文件已經有了數據;那么文件執行就會出錯。以下是一個JSP程序調用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>

    ? 當在測覽器中測覽 toservlet.jsp時;程序就會被重定向到toJSP.servlet。除了使用<jsp:forward>指令外,還可以使用<jsp:include>來包含一個Servlet程序。

    4.3 在Servlet程序中調用JSP

    ? 在Servlet程序中調用JSP的方法是:getServletConfig().getServletContext(). getRequestDispatcher("/jspexa/jsp/stj.jsp).forward(request,response);以下是上例中toservlet.jsp調用的Servlet程序,該程序又重新定向到/jspexa/jsp/stj.jsp,即經過兩次重定向,又轉回到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>

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

    5 中文顯示問題及其解決辦法

    ? 若在網頁中中文無法正常顯示,解決辦法如下:

    1.修改區域設置。在控制面板中選擇區域設置,將中文改為英語(美國),一切就會正常。如果還不正常,可重新啟動計算機。

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

    3.在編譯servlet時加入代碼選項:
    javac -encoding iso8859-1 文件名.java

    posted on 2006-11-15 20:12 lbfeng 閱讀(2781) 評論(0)  編輯  收藏 所屬分類: JSP&Servlet技術
    主站蜘蛛池模板: 亚洲宅男永久在线| 成人片黄网站A毛片免费| 国产免费无遮挡精品视频| 亚洲综合无码无在线观看| 卡1卡2卡3卡4卡5免费视频| 亚洲娇小性色xxxx| 在线免费不卡视频| 91香蕉国产线观看免费全集| 91亚洲精品麻豆| 国产免费69成人精品视频| 国产大片线上免费观看 | 91福利视频免费观看| 亚洲一级片免费看| 久久亚洲国产视频| 最近中文字幕mv免费高清电影| 一级毛片在播放免费| 亚洲图片在线观看| 日韩一级在线播放免费观看| 亚洲日韩在线观看免费视频| 国产成人综合亚洲一区| 亚洲色欲久久久综合网 | 亚洲宅男天堂a在线| 女人被弄到高潮的免费视频| 性xxxxx免费视频播放| 精品成人一区二区三区免费视频 | 在线观看免费视频网站色| 久久精品国产亚洲AV高清热| 国产亚洲A∨片在线观看| 国内一级一级毛片a免费| 最近中文字幕无吗免费高清| 免费毛片在线看片免费丝瓜视频| 国产成人免费午夜在线观看| 免费VA在线观看无码| 亚洲av永久无码精品三区在线4| 免费一看一级毛片全播放| 久久永久免费人妻精品| 亚洲AV日韩综合一区| 久久久无码精品亚洲日韩蜜桃| 国产亚洲av片在线观看播放| 亚洲2022国产成人精品无码区| 亚洲A∨无码无在线观看|