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

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

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

    隨筆 - 154  文章 - 60  trackbacks - 0
    <2007年9月>
    2627282930311
    2345678
    9101112131415
    16171819202122
    23242526272829
    30123456

    聲明:

    該blog是為了收集資料,認(rèn)識(shí)朋友,學(xué)習(xí)、提高技術(shù),所以本blog的內(nèi)容除非聲明,否則一律為轉(zhuǎn)載!!

    感謝那些公開自己技術(shù)成果的高人們!!!

    支持開源,尊重他人的勞動(dòng)!!

    常用鏈接

    留言簿(3)

    隨筆分類(148)

    隨筆檔案(143)

    收藏夾(2)

    其他

    學(xué)習(xí)(技術(shù))

    觀察思考(非技術(shù))

    搜索

    •  

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

     在Servlet之前Java服務(wù)器端編程使用C或Perl編寫復(fù)雜的CGI來(lái)實(shí)現(xiàn)來(lái)完成,Java Servlet API的出現(xiàn)極大地簡(jiǎn)化了Java在服務(wù)器端編程的復(fù)雜性同時(shí)能最大限度地發(fā)揮Java的的整體優(yōu)勢(shì)。
      在這個(gè)專題中我們由淺入深地向大家介紹Java Servlet的基本特征、開發(fā)環(huán)境的配置以及Servlet的一些主要API類。

    Servlet是一種獨(dú)立于平臺(tái)和協(xié)議的服務(wù)器端的Java應(yīng)用程序,可以生成動(dòng)態(tài)的Web頁(yè)面

    一、概述

    Servlet是一種獨(dú)立于平臺(tái)和協(xié)議的服務(wù)器端的Java應(yīng)用程序,可以生成動(dòng)態(tài)的Web頁(yè)面。

    Servlet是位于Web 服務(wù)器內(nèi)部的服務(wù)器端的Java應(yīng)用程序,與傳統(tǒng)的從命令行啟動(dòng)的Java應(yīng)用程序不同,Servlet由Web服務(wù)器進(jìn)行加載,該Web服務(wù)器必須包含支持Servlet的Java虛擬機(jī)。

    Java Servlet 與 Applet 的比較:

    相似之處:

    * 它們不是獨(dú)立的應(yīng)用程序,沒有main()方法。

    * 它們不是由用戶或程序員調(diào)用,而是由另外一個(gè)應(yīng)用程序(容器)調(diào)用。

    * 它們都有一個(gè)生存周期,包含init()和destroy()方法。

    不同之處:

    * Applet具有很好的圖形界面(AWT),與瀏覽器一起,在客戶端運(yùn)行。

    * Servlet 則沒有圖形界面,運(yùn)行在服務(wù)器端。

    Java Servlet 與 CGI(Common Gateway Interface) 的比較:

    與傳統(tǒng)的CGI和許多其他類似CGI的技術(shù)相比,Java Servlet具有更高的效率,更容易使用,功能更強(qiáng)大,具有更好的可移植性,更節(jié)省投資。在未來(lái)的技術(shù)發(fā)展過(guò)程中,Servlet有可能徹底取代CGI。

    * 高效

    在傳統(tǒng)的CGI中,每個(gè)請(qǐng)求都要啟動(dòng)一個(gè)新的進(jìn)程,如果CGI程序本身的執(zhí)行時(shí)間較短,啟動(dòng)進(jìn)程所需要的開銷很可能反而超過(guò)實(shí)際執(zhí)行時(shí)間。而在Servlet中,每個(gè)請(qǐng)求由一個(gè)輕量級(jí)的Java線程處理(而不是重量級(jí)的操作系統(tǒng)進(jìn)程)。

    在傳統(tǒng)CGI中,如果有N個(gè)并發(fā)的對(duì)同一CGI程序的請(qǐng)求,則該CGI程序的代碼在內(nèi)存中重復(fù)裝載了N次;而對(duì)于Servlet,處理請(qǐng)求的是N個(gè)線程,只需要一份Servlet類代碼。在性能優(yōu)化方面,Servlet也比CGI有著更多的選擇。

    * 方便

    Servlet提供了大量的實(shí)用工具例程,例如自動(dòng)地解析和解碼HTML表單數(shù)據(jù)、讀取和設(shè)置HTTP頭、處理Cookie、跟蹤會(huì)話狀態(tài)等。

    * 功能強(qiáng)大

    在Servlet中,許多使用傳統(tǒng)CGI程序很難完成的任務(wù)都可以輕松地完成。例如,Servlet能夠直接和Web服務(wù)器交互,而普通的CGI程序不能。Servlet還能夠在各個(gè)程序之間共享數(shù)據(jù),使得數(shù)據(jù)庫(kù)連接池之類的功能很容易實(shí)現(xiàn)。

    * 可移植性好

    Servlet用Java編寫,Servlet API具有完善的標(biāo)準(zhǔn)。因此,為IPlanet Enterprise Server寫的Servlet無(wú)需任何實(shí)質(zhì)上的改動(dòng)即可移植到Apache、Microsoft IIS或者WebStar。幾乎所有的主流服務(wù)器都直接或通過(guò)插件支持Servlet。

    * 節(jié)省投資

    不僅有許多廉價(jià)甚至免費(fèi)的Web服務(wù)器可供個(gè)人或小規(guī)模網(wǎng)站使用,而且對(duì)于現(xiàn)有的服務(wù)器,如果它不支持Servlet的話,要加上這部分功能也往往是免費(fèi)的(或只需要極少的投資)。

    Java Servlet 與 JSP(JavaServer Pages) 的比較:

    JavaServer Pages(JSP)是一種實(shí)現(xiàn)普通靜態(tài)HTML和動(dòng)態(tài)HTML混合編碼的技術(shù),JSP并沒有增加任何本質(zhì)上不能用Servlet實(shí)現(xiàn)的功能。但是,在JSP中編寫靜態(tài)HTML更加方便,不必再用println語(yǔ)句來(lái)輸出每一行HTML代碼。更重要的是,借助內(nèi)容和外觀的分離,頁(yè)面制作中不同性質(zhì)的任務(wù)可以方便地分開:比如,由頁(yè)面設(shè)計(jì)者進(jìn)行HTML設(shè)計(jì),同時(shí)留出供Servlet程序員插入動(dòng)態(tài)內(nèi)容的空間。

    Java Servlet API 2.2 簡(jiǎn)介

    Java Servlet API 2.2 的類和接口組成兩個(gè)Java 包,即:javax.servlet 和 javax.servlet.http(還包括javax.servlet.jsp包,不在本篇文章討論范圍之內(nèi))。

    javax.servlet 包提供了控制 Servlet 生命周期所必需的 Servlet 接口,是編寫 Servlet 時(shí)必須要實(shí)現(xiàn)的。

    javax.servlet.http 包提供了從Servlet 接口派生出的專門用于處理 HTTP 請(qǐng)求的抽象類和一般的工具類。所有的Servlet 對(duì)象都要實(shí)現(xiàn)Servlet 接口,大多數(shù)情況下是作為已經(jīng)實(shí)現(xiàn)了Servlet 接口的javax.servlet.GenericServlet 和 javax.servlet.http.HttpServlet 這兩個(gè)抽象類的子類來(lái)間接實(shí)現(xiàn)Servlet 接口。

    javax.servlet 包定義的類和接口:

    interface RequestDispatcher

    //定義一種對(duì)象,用于從客戶接受請(qǐng)求,并將請(qǐng)求發(fā)送到服務(wù)器上任何指定的資源,如一個(gè)Servlet 、JSP 或 HTML 文件。

    interface Servlet

    //定義了所有 Servlet 必須實(shí)現(xiàn)的方法。

    interface ServletConfig

    //定義Servlet config 對(duì)象,由Servlet 引擎用在 Servlet 初始化時(shí),向 Servlet 傳遞信息。

    interface ServletContext

    //定義了一系列方法,以便Servlet與其運(yùn)行的環(huán)境通信。

    interface ServletRequest

    //定義了用于向Servlet傳遞客戶請(qǐng)求信息的對(duì)象。

    interface ServletResponse

    //定義了一個(gè)對(duì)象,由Servlet用于向客戶發(fā)送響應(yīng)。

    interface SingleThreadModel

    //用于保證Servlet在任一時(shí)刻,只處理一個(gè)請(qǐng)求。

    class GenericServlet

    //繼承Servlet接口,定義了一個(gè)通用的,與協(xié)議無(wú)關(guān)的Servlet。

    class ServletInputStream

    //定義了一個(gè)輸入流,用于由Servlet從中讀取客戶請(qǐng)求的二進(jìn)制數(shù)據(jù)。

    class ServletOutputStream

    //定義了一個(gè)輸出流,用于由Servlet向客戶發(fā)送二進(jìn)制數(shù)據(jù)。

    class ServletException

    //定義了一個(gè)當(dāng)Servlet遇到問(wèn)題時(shí)可以拋出的異常。

    class UnavailableException

    //定義了一種異常,用于由Servlet指明它永遠(yuǎn)或暫時(shí)不可用。

    javax.servlet.http 包定義的類和接口:

    interface HttpServletRequest

    //繼承了ServletRequest 接口,為HTTPServlet 提供請(qǐng)求信息。

    interface HttpServletResponse

    //繼承了ServletResponse 接口,為HTTPServlet 輸出響應(yīng)信息提供支持。

    interface HttpSession

    //為維護(hù) HTTP 用戶的會(huì)話狀態(tài)提供支持。

    interface HttpSessionBindingListener

    //使得某對(duì)象在加入一個(gè)會(huì)話或從會(huì)話中刪除時(shí)能夠得到通知。

    interface HttpSessionContext

    //由Servlet 2.1 定義,該對(duì)象在新版本已不被支持。

    class Cookie

    //用在Servlet 中使用Cookie 技術(shù)

    class HttpServlet

    //定義了一個(gè)抽象類,繼承 GenericServlet 抽象類,應(yīng)被 HTTPServlet 繼承。

    class HttpSessionBindingEvent

    //定義了一種對(duì)象,當(dāng)某一個(gè)實(shí)現(xiàn)了HttpSessionBindingListener接口的對(duì)象被加入會(huì)話或從會(huì)//話中刪除時(shí),會(huì)收到該類對(duì)象的一個(gè)句柄

    class HttpUtils

    //提供了一系列便于編寫HTTPServlet 的方法。

    下面主要介紹javax.servlet.http提供的HTTP Servlet應(yīng)用編程接口。

    HTTP Servlet 使用一個(gè) HTML 表格來(lái)發(fā)送和接收數(shù)據(jù)。要?jiǎng)?chuàng)建一個(gè) HTTP Servlet,請(qǐng)擴(kuò)展 HttpServlet 類, 該類是用專門的方法來(lái)處理 HTML 表格的 GenericServlet 的一個(gè)子類。 HTML 表單是由 <FORM> 和 </FORM> 標(biāo)記定義的。表單中典型地包含輸入字段(如文本輸入字段、復(fù)選框、單選按鈕和選擇列表)和用于提交數(shù)據(jù)的按鈕。當(dāng)提交信息時(shí),它們還指定服務(wù)器應(yīng)執(zhí)行哪一個(gè)Servlet(或其它的程序)。 HttpServlet 類包含 init()、destroy()、service() 等方法。其中 init() 和 destroy() 方法是繼承的。

    (1) init() 方法

    在 Servlet 的生命期中,僅執(zhí)行一次 init() 方法。它是在服務(wù)器裝入 Servlet 時(shí)執(zhí)行的。 可以配置服務(wù)器,以在啟動(dòng)服務(wù)器或客戶機(jī)首次訪問(wèn) Servlet 時(shí)裝入 Servlet。 無(wú)論有多少客戶機(jī)訪問(wèn) Servlet,都不會(huì)重復(fù)執(zhí)行 init() 。

    缺省的 init() 方法通常是符合要求的,但也可以用定制 init() 方法來(lái)覆蓋它,典型的是管理服務(wù)器端資源。 例如,可能編寫一個(gè)定制 init() 來(lái)只用于一次裝入 GIF 圖像,改進(jìn) Servlet 返回 GIF 圖像和含有多個(gè)客戶機(jī)請(qǐng)求的性能。另一個(gè)示例是初始化數(shù)據(jù)庫(kù)連接。缺省的 init() 方法設(shè)置了 Servlet 的初始化參數(shù),并用它的 ServletConfig 對(duì)象參數(shù)來(lái)啟動(dòng)配置, 因此所有覆蓋 init() 方法的 Servlet 應(yīng)調(diào)用 super.init() 以確保仍然執(zhí)行這些任務(wù)。在調(diào)用 service() 方法之前,應(yīng)確保已完成了 init() 方法。

    (2) service() 方法

    service() 方法是 Servlet 的核心。每當(dāng)一個(gè)客戶請(qǐng)求一個(gè)HttpServlet 對(duì)象,該對(duì)象的service() 方法就要被調(diào)用,而且傳遞給這個(gè)方法一個(gè)"請(qǐng)求"(ServletRequest)對(duì)象和一個(gè)"響應(yīng)"(ServletResponse)對(duì)象作為參數(shù)。 在 HttpServlet 中已存在 service() 方法。缺省的服務(wù)功能是調(diào)用與 HTTP 請(qǐng)求的方法相應(yīng)的 do 功能。例如, 如果 HTTP 請(qǐng)求方法為 GET,則缺省情況下就調(diào)用 doGet() 。Servlet 應(yīng)該為 Servlet 支持的 HTTP 方法覆蓋 do 功能。因?yàn)?HttpServlet.service() 方法會(huì)檢查請(qǐng)求方法是否調(diào)用了適當(dāng)?shù)奶幚矸椒ǎ槐匾采w service() 方法。只需覆蓋相應(yīng)的 do 方法就可以了。

    當(dāng)一個(gè)客戶通過(guò)HTML 表單發(fā)出一個(gè)HTTP POST請(qǐng)求時(shí),doPost()方法被調(diào)用。與POST請(qǐng)求相關(guān)的參數(shù)作為一個(gè)單獨(dú)的HTTP 請(qǐng)求從瀏覽器發(fā)送到服務(wù)器。當(dāng)需要修改服務(wù)器端的數(shù)據(jù)時(shí),應(yīng)該使用doPost()方法。

    當(dāng)一個(gè)客戶通過(guò)HTML 表單發(fā)出一個(gè)HTTP GET請(qǐng)求或直接請(qǐng)求一個(gè)URL時(shí),doGet()方法被調(diào)用。與GET請(qǐng)求相關(guān)的參數(shù)添加到URL的后面,并與這個(gè)請(qǐng)求一起發(fā)送。當(dāng)不會(huì)修改服務(wù)器端的數(shù)據(jù)時(shí),應(yīng)該使用doGet()方法。

    Servlet的響應(yīng)可以是下列幾種類型:

    一個(gè)輸出流,瀏覽器根據(jù)它的內(nèi)容類型(如text/HTML)進(jìn)行解釋。

    一個(gè)HTTP錯(cuò)誤響應(yīng), 重定向到另一個(gè)URL、servlet、JSP。

    (3) destroy() 方法

    destroy() 方法僅執(zhí)行一次,即在服務(wù)器停止且卸裝Servlet 時(shí)執(zhí)行該方法。典型的,將 Servlet 作為服務(wù)器進(jìn)程的一部分來(lái)關(guān)閉。缺省的 destroy() 方法通常是符合要求的,但也可以覆蓋它,典型的是管理服務(wù)器端資源。例如,如果 Servlet 在運(yùn)行時(shí)會(huì)累計(jì)統(tǒng)計(jì)數(shù)據(jù),則可以編寫一個(gè) destroy() 方法,該方法用于在未裝入 Servlet 時(shí)將統(tǒng)計(jì)數(shù)字保存在文件中。另一個(gè)示例是關(guān)閉數(shù)據(jù)庫(kù)連接。

    當(dāng)服務(wù)器卸裝 Servlet 時(shí),將在所有 service() 方法調(diào)用完成后,或在指定的時(shí)間間隔過(guò)后調(diào)用 destroy() 方法。一個(gè)Servlet 在運(yùn)行service() 方法時(shí)可能會(huì)產(chǎn)生其它的線程,因此請(qǐng)確認(rèn)在調(diào)用 destroy() 方法時(shí),這些線程已終止或完成。

    (4) GetServletConfig()方法

    GetServletConfig()方法返回一個(gè) ServletConfig 對(duì)象,該對(duì)象用來(lái)返回初始化參數(shù)和ServletContext。ServletContext 接口提供有關(guān)servlet 的環(huán)境信息。

    (5) GetServletInfo()方法

    GetServletInfo()方法是一個(gè)可選的方法,它提供有關(guān)servlet 的信息,如作者、版本、版權(quán)。

    當(dāng)服務(wù)器調(diào)用sevlet 的Service()、doGet()和doPost()這三個(gè)方法時(shí),均需要 "請(qǐng)求"和"響應(yīng)"對(duì)象作為參數(shù)。"請(qǐng)求"對(duì)象提供有關(guān)請(qǐng)求的信息,而"響應(yīng)"對(duì)象提供了一個(gè)將響應(yīng)信息返回給瀏覽器的一個(gè)通信途徑。

    javax.servlet 軟件包中的相關(guān)類為ServletResponse和ServletRequest,而javax.servlet.http 軟件包中的相關(guān)類為HttpServletRequest 和 HttpServletResponse。

    Servlet 通過(guò)這些對(duì)象與服務(wù)器通信并最終與客戶機(jī)通信。Servlet 能通過(guò)調(diào)用"請(qǐng)求"對(duì)象的方法獲知客戶機(jī)環(huán)境,服務(wù)器環(huán)境的信息和所有由客戶機(jī)提供的信息。Servlet 可以調(diào)用"響應(yīng)"對(duì)象的方法發(fā)送響應(yīng),該響應(yīng)是準(zhǔn)備發(fā)回客戶機(jī)的。


    進(jìn)行Servlet開發(fā)所需要的基本環(huán)境是JSDK以及一個(gè)支持Servlet的Web服務(wù)器

       編寫Servlet所需要的開發(fā)環(huán)境

      進(jìn)行Servlet開發(fā)所需要的基本環(huán)境是JSDK以及一個(gè)支持Servlet的Web服務(wù)器。

        1.JSDK(Java Servlet Development Kit)

      JSDK包含了編譯Servlet應(yīng)用程序所需要的Java類庫(kù)以及相關(guān)的文檔。對(duì)于利用Java 1.1進(jìn)行開發(fā)的用戶,必須安裝JSDK。JSDK已經(jīng)被集成進(jìn)Java 1.2 Beta版中,如果利用Java 1.2或以上版本進(jìn)行開發(fā),則不必安裝JSDK。

      JSDK可以在Javasoft公司的站點(diǎn)免費(fèi)下載,其地址是:   http://www.sun.com/software/jwebserver/redirect.html
     
      2.支持Servlet的Web服務(wù)器

      Servlet需要運(yùn)行在支持Servlet的Web服務(wù)器上。目前支持Servlet的Web服務(wù)器SUN公司的JSWDK1.0.1。如果現(xiàn)有的Web服務(wù)器不支持Servlet,則可以利用一些第三方廠商的服務(wù)器增加件(add-ons)來(lái)使Web服務(wù)器支持Servlet,這其中Live Software公司(http://www.livesoftware.com)提供了一種稱為JRun的產(chǎn)品,通過(guò)安裝JRun的相應(yīng)版本,可以使Microsoft IIS和Netscape Web Server支持Servlet。

      開發(fā)Servlet的過(guò)程

      下面舉一個(gè)簡(jiǎn)單的Servlet 例子來(lái)說(shuō)明開發(fā)Servlet的過(guò)程。

      1.編寫Servlet代碼

      Java Servlet API是一個(gè)標(biāo)準(zhǔn)的Java擴(kuò)展程序包,包含兩個(gè)Package∶javax.servlet和javax.servlet.http。對(duì)于想開發(fā)基于客戶自定義協(xié)議的開發(fā)者,應(yīng)該使用javax.servlet包中的類與界面;對(duì)于僅利用HTTP協(xié)議與客戶端進(jìn)行交互的開發(fā)者,則只需要使用javax.servlet.http包中的類與界面進(jìn)行開發(fā)即可。

      下面是一個(gè)servlet的程序代碼(RequestInfoExample.java)∶

    import java.io.*;
    import java.servlet.*;
    import javax.servlet.*;

    public class RequestInfoExample 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>");
       out.println("<head>");
       out.println("<title>Request Information Example</title>");
       out.println("</head>");
       out.println("<body>");
       out.println("<h3>Request Information Example</h3>");
       out.println("Method: " + request.getMethod());
       out.println("Request URI: " + request.getRequestURI());
       out.println("Protocol: " + request.getProtocol());
       out.println("PathInfo: " + request.getPathInfo());
       out.println("Remote Address: " + request.getRemoteAddr());
       out.println("</body>");
       out.println("</html>");
      }

      public void doPost(HttpServletRequest request, HttpServletResponse res)
      throws IOException, ServletException
      {
       doGet(request, response);
      }
    }

      該servlet實(shí)現(xiàn)如下功能∶當(dāng)用戶通過(guò)瀏覽器訪問(wèn)該servlet時(shí),該servlet向客戶端瀏覽器返回一個(gè)HTML頁(yè)面∶

    ------------------------------------------------
    Request Information Example

    Method: GET
    Request URI: /examples/servlet/RequestInfoExample
    Protocol: HTTP/1.1
    Path Info: null
    Remote Address: 127.0.0.1
    --------------------------------------------------

      有關(guān)servlet程序說(shuō)明∶

      * 基于HTTP協(xié)議的servlet必須引入javax.servlet和javax.servlet.http包;

      * HelloServlet從類HttpServlet派生,HttpServlet是GenericServlet的一個(gè)派生類,通過(guò) GenericServlet實(shí)現(xiàn)了Servlet界面。HttpServlet為基于HTTP協(xié)議的servlet提供了基本的支持;

      * HttpServletRequest對(duì)象包含了客戶端請(qǐng)求的信息,可以通過(guò)該參數(shù)取得客戶端的一些信息(例如IP地址、瀏覽器類型等)以及HTTP請(qǐng)求類型(例如GET、HEAD、POST、PUT等);HttpServletResponse對(duì)象用于完成Servlet與客戶端的交互,通過(guò)調(diào)用HttpServletResponse.getOutputStream()客戶取得向客戶端進(jìn)行輸出的輸出流,向客戶端發(fā)送HTML頁(yè)面。

      * 編寫了doGet方法,對(duì)于HTML POST 請(qǐng)求,調(diào)用Servlet 的doPost()方法。

      2.編譯Servlet代碼

      利用JDK 1.2.2 對(duì)Servlet代碼進(jìn)行編譯(假設(shè)Web服務(wù)器采用jswdk-1.0.1),其命令行為:

      c:\> javac -d C:\jswdk-1.0.1\examples\WEB-INF\servlets HelloServlet.java

      進(jìn)行編譯時(shí)必須確保HelloServlet.java 文件拷貝到目錄C:\jswdk-1.0.1\examples\WEB- INF\servlets 下面。
     
      3.測(cè)試Servlet

      現(xiàn)在可以對(duì)HelloServlet進(jìn)行測(cè)試了,打開瀏覽器,鍵入:

      http://localhost:8080/examples/servlet/RequestInfoExample

      其中l(wèi)ocalhost是安裝有jswdk-1.0.1的機(jī)器,8080是端口號(hào)。



    希爾排序法基本思想是:取一個(gè)間隔,將長(zhǎng)序列分成若干短的子序列,對(duì)每個(gè)子序列進(jìn)行直插排序;然后逐漸縮小間隔,重復(fù)以上過(guò)程,直到間隔為1

        前面我們學(xué)習(xí)了兩種插入排序法,但當(dāng)要排序的數(shù)組長(zhǎng)度越長(zhǎng)并且數(shù)值越不成順序,比較和交換的次數(shù)就越多,效率越低。因此D.L.Shell在1959年提出了縮小增量排序法(又叫希爾排序法),基本思想是:取一個(gè)間隔,將長(zhǎng)序列分成若干短的子序列,對(duì)每個(gè)子序列進(jìn)行直插排序;然后逐漸縮小間隔,重復(fù)以上過(guò)程,直到間隔為1。可以看到這種算法,較好的克服了直接插入排序法的不足。


      下面是示例:

    8 7 4 3 6 1 //是要排序的數(shù)值,我們以一半的長(zhǎng)度為間隔3
    3 7 4 8 6 1 //第一次,取得3,小于前面的8,交換位置
    3 6 4 8 7 1 //第二次,取得6,小于前面的7,交換位置
    3 6 1 8 7 4 //第三次,取得1,小于前面的4,交換位置
    1 6 3 4 7 8 //第四次,再縮小間隔,為2,取得1小于3,交換位置,取得7,大于前面的3,不變;取得8大于6,不變,取得4小于8,交換位置
    1 3 4 6 7 8 //第五次,再縮小間隔,為1,取得6,大于1,不變;取得3小于6,交換位置;取得4,小于6,交換位置;取得7,大于前面的6,不變;取得8 ,大于7,不變

      以下是代碼:

    void paixu( ) //用希爾排序法,
    {
      int N=13;// N為前后紀(jì)錄位置的增量
      for (int Z= N/2; Z; Z = Z/2)//每次縮小增量
       for (int i = Z; i < N; i++)//從增兩大小開始比較
       {
        int temp = apai[i]; //將后一個(gè)備份
        for (int j = i; j >= Z && temp < a[j - Z]; j -= Z) //與他在同一個(gè)子序列的數(shù)一個(gè)個(gè)的較
        {
         a[j] = a[j -Z]; //如果小于,就交換
        }//end for
        a[j] = temp; //找到合適的插入點(diǎn),放入其中
       }//end for
    }//end


      我們?cè)賮?lái)看最后一種關(guān)于數(shù)組的排序方法,就是快速排序法,它是目前最快的一種排序的方法.它的基本思想是:通過(guò)一趟排序?qū)⒋判虻挠涗浄指顬楠?dú)立的兩部分,其中一部分記錄的數(shù)值均比另一部分記錄的數(shù)值小,然后繼續(xù)分別對(duì)這兩部分進(jìn)行排序,直到整個(gè)序列有序?yàn)橹?

      具體做法: 任取待排序列的某個(gè)記錄(我們可以取第一個(gè)數(shù))作為基準(zhǔn),按照該數(shù)值大小,將整個(gè)序列分成兩個(gè)序列——左側(cè)的所有記錄的數(shù)值都比基準(zhǔn)小(或者相等),右側(cè)的都比基準(zhǔn)大,基準(zhǔn)則放在兩個(gè)子序列之間,顯然這時(shí)基準(zhǔn)放在了最后應(yīng)該放置的位置。分別對(duì)左右子序列重復(fù)上面的過(guò)程,直到最后所有的記錄都放在相應(yīng)的位置。

      示例如下:

    7 8 4 3 6 1 //是要排序的數(shù)值
    1 8 4 3 6 //第一次,取得7,作為基準(zhǔn),1為right值,7>1,交換位置
    1 4 3 6 8 //第二次, 8為left值,7<8,放到最后;
    1 4 3 6 8 //第三次,left取得4,小于7,放到前面,
    1 4 6 3 8 //第四次,right取6,小于7,放到前面
    1 4 6 3 8 //第五次,left=right=3,小于7,放到前面,
    1 4 6 3 7 8 //7放入合適位置,第一趟排序完成
    //后面,在以1為基準(zhǔn)排序
    ……
    //直到成功

      代碼如下:

    void paixu(int a[],int low,int high;)//用快速排序法
    {
      // low, high表示掃描的范圍

      int pivot;//存放中心索引及其值的局部變量
      int scanup,scandown,mid;//用于掃描的索引
      if (high-low<=0) //如果數(shù)組中的元素少于兩個(gè),則返回
       return;
      else
       if(high-low==1) //如果有兩個(gè)元素,對(duì)其進(jìn)行比較
       {
        if(apai[high]<apai[low]) //如果后一個(gè)比前一個(gè)小,
         Swap(apai[low],apai[high]);//那么交換位置
         return;
       }//end if
      mid=(low+high)/2;//取得中心索引
      pivot=apai[mid];//將中間索引的值,賦給pivot
      Swap(apai[mid],apai[low]);//交換pivot及低端元素的值
      Scanup=low+1;
      Scandown=high;//初始化掃描索引scanup和scandown
      do{
       //從低端子表向上掃描,當(dāng)scanup進(jìn)入高端子表或遇到大于pivot的元素時(shí)結(jié)束.
       while(scanup<=scandown && apai[scanup]<=pivot)
        scanup++;
        //從高端子表向下掃描,當(dāng)scandown遇到小于或等于pivot的元素時(shí)結(jié)束
       while(piovt<apai[scandown])
        scandown--;
        //如果兩個(gè)索引還在各自的子表中,則表示兩個(gè)元素錯(cuò)位,將兩個(gè)元素?fù)Q位
        if(scanup<scandown)
         Swap(apai[scanup],apai[scandown]);
      }while(scanup<scandown);
      //將pivot拷貝到scandown位置,分開兩個(gè)子表
      apai[low]=apai[scandown];
       apai[scandown]=pivot;
      //如果低端子表(low至scandown-1)有2個(gè)或更多個(gè)元素,則進(jìn)行遞歸調(diào)用
      if(low<scandown-1)
       paixu(apai,low,scandown-1);
       //如果高端子表(scandown+1至high) 有2個(gè)或更多個(gè)元素,則進(jìn)行遞歸調(diào)用
      if(scandown+1<high)
       paixu(apai, scandown+1, high);
    }

      關(guān)于排序的問(wèn)題已經(jīng)夠多了,就到這里吧,如果大家有興趣,可以看已看這方面的書.



    HttpServlet 是從GenericServlet 繼承而來(lái),因此它具有GenericServlet 類似的方法和對(duì)象,是我們使用Servlet編程經(jīng)常用到的包,它支持HTTP 的post 和 get 等方法。

      編程思路:下面的例子,運(yùn)行結(jié)果是輸出簡(jiǎn)單地返回客戶發(fā)送給服務(wù)器的請(qǐng)求行和頭部信息,以及一些可訪問(wèn)的HTTP 信息等。


      SnoopServlet.java 的源代碼如下:

    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.Enumeration;
    import javax.servlet.*;
    import javax.servlet.http.*;


    public class SnoopServlet extends HttpServlet {

      public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException
      {
       PrintWriter out = response.getWriter();
       response.setContentType("text/plain");

       out.println("Snoop Servlet");
       out.println();
       out.println("Servlet init parameters:");
       Enumeration e = getInitParameterNames();
       while (e.hasMoreElements()) {
        String key = (String)e.nextElement();
        String value = getInitParameter(key);
        out.println(" " + key + " = " + value);
       }
       out.println();

       out.println("Context init parameters:");
       ServletContext context = getServletContext();
       Enumeration enum = context.getInitParameterNames();
       while (enum.hasMoreElements()) {
        String key = (String)enum.nextElement();
        Object value = context.getInitParameter(key);
        out.println(" " + key + " = " + value);
       }
       out.println();

       out.println("Context attributes:");
       enum = context.getAttributeNames();
       while (enum.hasMoreElements()) {
        String key = (String)enum.nextElement();
        Object value = context.getAttribute(key);
        out.println(" " + key + " = " + value);
       }
       out.println();

       out.println("Request attributes:");
       e = request.getAttributeNames();
       while (e.hasMoreElements()) {
        String key = (String)e.nextElement();
        Object value = request.getAttribute(key);
        out.println(" " + key + " = " + value);
       }
       out.println();
       out.println("Servlet Name: " + getServletName());
       out.println("Protocol: " + request.getProtocol());
       out.println("Scheme: " + request.getScheme());
       out.println("Server Name: " + request.getServerName());
       out.println("Server Port: " + request.getServerPort());
       out.println("Server Info: " + context.getServerInfo());
       out.println("Remote Addr: " + request.getRemoteAddr());
       out.println("Remote Host: " + request.getRemoteHost());
       out.println("Character Encoding: " + request.getCharacterEncoding());
       out.println("Content Length: " + request.getContentLength());
       out.println("Content Type: "+ request.getContentType());
       out.println("Locale: "+ request.getLocale());
       out.println("Default Response Buffer: "+ response.getBufferSize());
       out.println();
       out.println("Parameter names in this request:");
       e = request.getParameterNames();
       while (e.hasMoreElements()) {
        String key = (String)e.nextElement();
        String[] values = request.getParameterValues(key);
        out.print(" " + key + " = ");
        for(int i = 0; i < values.length; i++) {
          out.print(values[i] + " ");
        }
        out.println();
       } 
       out.println();
       out.println("Headers in this request:");
       e = request.getHeaderNames();
       while (e.hasMoreElements()) {
         String key = (String)e.nextElement();
         String value = request.getHeader(key);
         out.println(" " + key + ": " + value);
       }
       out.println();
       out.println("Cookies in this request:");
       Cookie[] cookies = request.getCookies();
       if (cookies != null) {
        for (int i = 0; i < cookies.length; i++) {
         Cookie cookie = cookies[i];
         out.println(" " + cookie.getName() + " = "+ cookie.getValue());
        }
       }
       out.println();

       out.println("Request Is Secure: " + request.isSecure());
       out.println("Auth Type: " + request.getAuthType());
       out.println("HTTP Method: " + request.getMethod());
       out.println("Remote User: " + request.getRemoteUser());
       out.println("Request URI: " + request.getRequestURI());
       out.println("Context Path: " + request.getContextPath());
       out.println("Servlet Path: " + request.getServletPath());
       out.println("Path Info: " + request.getPathInfo());
       out.println("Path Trans: " + request.getPathTranslated());
       out.println("Query String: " + request.getQueryString());

       out.println();
       HttpSession session = request.getSession();
       out.println("Requested Session Id: " +
       request.getRequestedSessionId());
       out.println("Current Session Id: " + session.getId());
       out.println("Session Created Time: " + session.getCreationTime());
       out.println("Session Last Accessed Time: " +session.getLastAccessedTime());
       out.println("Session Max Inactive Interval Seconds: " + session.getMaxInactiveInterval());
       out.println();
       out.println("Session values: ");
       Enumeration names = session.getAttributeNames();
       while (names.hasMoreElements()) {
        String name = (String) names.nextElement();
        out.println(" " + name + " = " + session.getAttribute(name));
       }
      }
    }

      編程技巧說(shuō)明:

      程序輸出Init Parameters(初始化參數(shù))、Attribute names in this request、Parameter names in this request、Headers in this request、Cookies in this request 和 Session Information等信息。
    方法getRequestURI返回的對(duì)象URI 是作為URL 的一部分,是去掉URL 中用于指定機(jī)器的那部分;方法getPathInfo 返回的字符串是客戶向Servlet 傳送的各種選項(xiàng),這些選項(xiàng)是跟在Servlet 的URL 之后的,方法getPathTranslated 返回的字符串是Servlet 的自己的絕對(duì)路徑名,SnoopServlet.class 文件位置是C:\jswdk-1.0.1\examples\WEB-INF\servlets\SnoopServlet.class,則方法getPathTranslated 返回的字符串值就是它。

      在瀏覽器中輸入如下的地址:

    http://localhost:8080/examples/servlet/SnoopServlet
      則會(huì)輸出結(jié)果。


    Cookie 是一小塊可以嵌入HTTP 請(qǐng)求和響應(yīng)中的數(shù)據(jù),它在服務(wù)器上產(chǎn)生,并作為響應(yīng)頭域的一部分返回用戶。瀏覽器收到包含Cookie 的響應(yīng)后,會(huì)把Cookie 的內(nèi)容用“關(guān)鍵字/值” 對(duì)的形式寫入到一個(gè)客戶端專為存放Cookie 的文本文件中。瀏覽器會(huì)把Cookie 及隨后產(chǎn)生的請(qǐng)求發(fā)給相同的服務(wù)器,服務(wù)器可以再次讀取Cookie 中存Cookie 可以進(jìn)行有效期設(shè)置,過(guò)期的Cookie 不會(huì)發(fā)送給服務(wù)器。


      Servlet API 提供了一個(gè)Cookie 類,封裝了對(duì)Cookie 的一些操作。Servlet 可以創(chuàng)建一個(gè)新的Cookie,設(shè)置它的關(guān)鍵字、值及有效期等屬性,然后把Cookie 設(shè)置在HttpServletResponse 對(duì)象中發(fā)回瀏覽器,還可以從HttpServletRequest 對(duì)象中獲取Cookie。

      編程思路:Cookie 在實(shí)際的Servlet 編程中是很廣泛應(yīng)用,下面是一個(gè)從Servlet 中獲取Cookie 信息的例子。

      ShowCookies.java 的源代碼如下:

    import javax.servlet.*;
    import javax.servlet.http.*;

    /**
    * <p>This is a simple servlet that displays all of the
    * Cookies present in the request
    */

    public class ShowCookies extends HttpServlet
    {
     public void doGet(HttpServletRequest req, HttpServletResponse resp)
     throws ServletException, java.io.IOException
     {

      // Set the content type of the response
      resp.setContentType("text/html;charset=gb2312");

      // Get the PrintWriter to write the response
      java.io.PrintWriter out = resp.getWriter();

      // Get an array containing all of the cookies
      Cookie cookies[] = req.getCookies();

      // Write the page header
      out.println("<html>");
      out.println("<head>");
      out.println("<title>Servlet Cookie Information</title>");
      out.println("</head>");
      out.println("<body>");

      if ((cookies == null) || (cookies.length == 0)) {
       out.println("沒有 cookies ");
      }
      else {
       out.println("<center><h1>響應(yīng)消息中的Cookies 信息 </h1>");
       // Display a table with all of the info
       out.println("<table border>");
       out.println("<tr><th>Name</th><th>Value</th>" + "<th>Comment</th><th>Max Age</th></tr>");
       for (int i = 0; i < cookies.length; i++) {
        Cookie c = cookies[i];
        out.println("<tr><td>" + c.getName() + "</td><td>" +
        c.getValue() + "</td><td>" + c.getComment() + "</td><td>" + c.getMaxAge() + "</td></tr>");
      }
      out.println("</table></center>");
     }
     // Wrap up
     out.println("</body>");
     out.println("</html>");
     out.flush();
    }

    /**
    * <p>Initialize the servlet. This is called once when the
    * servlet is loaded. It is guaranteed to complete before any
    * requests are made to the servlet
    * @param cfg Servlet configuration information
    */

    public void init(ServletConfig cfg)
    throws ServletException
    {
     super.init(cfg);
    }

    /**
    * <p>Destroy the servlet. This is called once when the servlet
    * is unloaded.
    */

    public void destroy()
    {
     super.destroy();
    }
    }

      注意:Cookie 進(jìn)行服務(wù)器端與客戶端的雙向交流,所以它涉及到安全性問(wèn)題。

     使用Java Servlet API 進(jìn)行會(huì)話管理

      javax.servlet.http.HttpSession 接口封裝了HTTP 會(huì)話的細(xì)節(jié),該會(huì)話與一段時(shí)間內(nèi)特定的Web 客戶對(duì)Web 服務(wù)器的多個(gè)請(qǐng)求相關(guān)。管理會(huì)話數(shù)據(jù)主要涉及到3個(gè)方面:會(huì)話交換、會(huì)話重定位和會(huì)話持久性,只有實(shí)現(xiàn)了java.io.Serializable 接口的數(shù)據(jù)對(duì)象才能夠被交換、重定位和保持。這個(gè)接口主要是讓對(duì)象具有序列化的能力,它可以將對(duì)象的狀態(tài)信息寫入任意的輸出流中如:文件、網(wǎng)絡(luò)連接等。

      編程思路:下面是實(shí)現(xiàn)一個(gè)簡(jiǎn)單在商場(chǎng)購(gòu)物的例子,當(dāng)用戶選購(gòu)商品(糖果、收音機(jī)和練習(xí)簿)放入購(gòu)物袋中,保存選購(gòu)的商品信息。

      ShowBuy.java 的源代碼如下:

    import javax.servlet.*;
    import javax.servlet.http.*;
    import java.io.*;
    import java.util.*;

    public class ShowBuy extends HttpServlet
    {
     public void doGet(HttpServletRequest req, HttpServletResponse res)
     throws ServletException, java.io.IOException
     {
      String[] item={"糖果","收音機(jī)","練習(xí)簿"};
      //獲取會(huì)話對(duì)象
      HttpSession session=req.getSession(true);
      //獲取選擇的商品數(shù)目
      Integer itemCount=(Interger) session.getValue("itemCount");
      //如果沒放入商品則數(shù)目為0
      if (itemCount==null){
       itemCount=new Integer(0);
      }

      // Set the content type of the response
      res.setContentType("text/html;charset=gb2312");
      PrintWriter out=res.getWriter();

      //取得POST上來(lái)的表單信息
      String[] itemsSelected;
      String itemName;
      itemsSelected=req.getParameterValues("item");
      //將選中的商品放入會(huì)話對(duì)象
      if(itemsSelected !=null){
       for(int i=0;i<itemsSelected.length;i++){
        itemName=itemsSelected[i];
        itemCount=new Integer(itemCount.intValue()+1);
        session.putValue("Item" + itemCount,itemName);
        //將商品名稱定義為ItemX
        session.putValue("itemCount",itemCount);
        //將商品數(shù)量放入會(huì)話對(duì)象
       }
      }

      // Write the page header
      out.println("<html>");
      out.println("<head>");
      out.println("<title>購(gòu)物袋的內(nèi)容</title>");
      out.println("</head>");
      out.println("<body>");
      out.println("<center><h1>你放在購(gòu)物袋中的商品是: </h1></center>");
      //將購(gòu)物袋的內(nèi)容寫入頁(yè)面
      for (int i = 1; i < itemCount.intValue(); i++) {
       String item =(String) session.getValue("Item"+i);
       //取出商品名稱
       out.println(items[Integer.parseInt(item)]);
       out.println("<BR>");
      }
      // Wrap up
      out.println("</body>");
      out.println("</html>");
      out.close();
     }
    }

      客戶端的ShowBuy.html 的源代碼如下:

    <HTML>
    <HEAD>
     <TITLE>購(gòu)物袋的實(shí)例 </TITLE>
    </HEAD>
    <BODY>
     <CENTER><H1>百貨商場(chǎng)</H1></CENTER>
     <HR>
     <FORM ACTION='servlet/ShowBuy" METHOD="POST">
      選購(gòu)商品
      <p><INPUT TYPE="Checkbox" NAME="item" VALUE="0">
       第一種:糖果</p>
      <p><INPUT TYPE="Checkbox" NAME="item" VALUE="1">
       第二種:收音機(jī)</p>
      <p><INPUT TYPE="Checkbox" NAME="item" VALUE="2">
       第三種:練習(xí)簿</p>
      <HR>
      <INPUT TYPE="Submit" NAME="bt_submit" VALUE="加入購(gòu)物袋">
     </FORM>
    </BODY>
    </HTML>

      編程技巧說(shuō)明:

      在Servlet 中進(jìn)行會(huì)話管理時(shí),首先要獲得會(huì)話對(duì)象。HttpServletRequest.getSession()對(duì)象返回與請(qǐng)求相關(guān)的當(dāng)前HttpSession 對(duì)象,并且當(dāng)該對(duì)象不存在時(shí)就新創(chuàng)建一個(gè)對(duì)象;HttpServletRequest.getSession(true)實(shí)現(xiàn)相同的功能。如果參數(shù)是false,當(dāng)不存在會(huì)話對(duì)象時(shí),將返回一個(gè)null 值。

    //獲取會(huì)話對(duì)象
    HttpSession session=req.getSession(true);
    //獲取選擇的商品數(shù)目
    Integer itemCount=(Interger) session.getValue("itemCount");

      具體操作時(shí),當(dāng)用戶選擇商品后,單擊“加入購(gòu)物袋"按鈕,Servlet 輸出用戶選擇的商品。

    posted on 2007-09-27 11:31 lk 閱讀(789) 評(píng)論(0)  編輯  收藏 所屬分類: j2ee
    主站蜘蛛池模板: 亚洲精品蜜桃久久久久久| 日本成人在线免费观看| 久久99国产亚洲高清观看首页| 羞羞漫画在线成人漫画阅读免费 | a色毛片免费视频| 国产精品亚洲一区二区三区在线| 一级黄色免费大片| av在线亚洲欧洲日产一区二区| 农村寡妇一级毛片免费看视频| 久久亚洲av无码精品浪潮| 一个人看的免费观看日本视频www| 亚洲高清偷拍一区二区三区| 全黄A免费一级毛片| 亚洲精品无码成人AAA片| 男人j进入女人j内部免费网站| 久久久久亚洲av无码专区喷水| av无码免费一区二区三区| 日本亚洲精品色婷婷在线影院| 午夜视频在线在免费| 免费播放美女一级毛片| 亚洲中文字幕无码不卡电影| 免费黄色电影在线观看| www.亚洲成在线| 大胆亚洲人体视频| 青柠影视在线观看免费| 亚洲精品中文字幕乱码影院| 成人在线免费观看| eeuss影院www天堂免费| 亚洲男人天堂2017| 免费无码又爽又刺激毛片| 一个人看的www在线免费视频| 亚洲精品免费视频| 好男人视频在线观看免费看片| 黄色免费网址在线观看| 久久久久久亚洲精品中文字幕| 丁香花免费完整高清观看 | 一个人看的在线免费视频| 亚洲视频国产视频| 日批日出水久久亚洲精品tv| 国产羞羞的视频在线观看免费| 亚洲av乱码一区二区三区香蕉|