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

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

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

    即使世界明天毀滅,我也要在今天種下我的葡萄樹。
    posts - 112, comments - 14, trackbacks - 0, articles - 11

    Servlet容器工作原理

    Posted on 2006-05-24 17:08 閱讀(224) 評論(0)  編輯  收藏 所屬分類: WEB Design

    本文介紹servlet 容器的基本原理。現(xiàn)有兩個Servlet容器,第一個很簡單,第二個則是根據(jù)第一個寫出。為了使第一個容器盡量簡單,所以沒有做得很完整。復雜一些的 servlet 容器 (包括 TOMCAT 4 和 5) 可以參考其他資料。

    兩個servlet容器都處理簡單的servlet及staticResource。您可以使用 webroot/ 目錄下的 PrimitiveServlet 來測試它。復雜一些的 servlet會超出這些容器的容量,創(chuàng)建復雜servlet容器不是本文的內容,所以在這里就不詳細介紹了。

      兩個應用程序的類都封裝在ex02.pyrmont 包下。在理解應用程序如何
    運作 之前,您必須熟悉 javax.servlet.Servlet 接口。首先就來介紹這個接口。隨后,就介紹 servlet 容器服務servlet 的具體內容。

      javax.servlet.Servlet 接口

      servlet編程,需要引用以下兩個類和接口:javax.servlet 和 javax.servlet.http,在這些類和接口中,javax.servlet.Servlet接口尤為重要。所有的 servlet 必須實現(xiàn)這個接口或繼承已實現(xiàn)這個接口的類。

      Servlet 接口有五個方法,如下:

     public void init(ServletConfig config) throws ServletException
     public void
    service (ServletRequest request, ServletResponse response) throws ServletException, java .io.IOException
     public void destroy()
     public ServletConfig getServletConfig()
     public java.lang.String getServletInfo()

      init、service和 destroy 方法是 Servlet 生命周期的方法。當 Servlet 類實例化后,容器加載 init,以通知 servlet 它已進入服務行列。init 方法必須被加載,Servelt 才能接收和請求。如果要載入數(shù)據(jù)庫驅動程序、初始化一些值等等,程序員可以重寫這個方法。在其他情況下,這個方法一般為空。

      service 方法由 Servlet 容器調用,以允許 Servlet 響應一個請求。Servlet 容器傳遞 javax.servlet.ServletRequest 對象和 javax.servlet.ServletResponse 對象。ServletRequest 對象包含客戶端 HTTP 請求信息,ServletResponse 則封裝servlet 響應。通過這兩個對象,您可以寫一些需要 servlet怎樣服務和客戶怎樣請求的代碼。

      從service中刪除Servlet實例之前,容器調用destroy方法。在servlet容器關閉或servlet 容器需要更多的內存時,就調用它。這個方法只有在servlet 的service 方法內的所有線程都退出的時候,或在超時的時候才會被調用。在 servlet 容器調用 destroy方法之后,它將不再調用 servlet的 service方法。

      destroy 方法給了servlet機會,來清除所有空閑資源(比如:內存,文件處理和線程),以確保在內存的持續(xù)狀態(tài)和 servlet的當前狀態(tài)是同步的。Listing 2.1 包含了PrimitiveServlet 的代碼,此servlet非常簡單,可以用它來測試本文的servlet容器應用程序。

      PrimitiveServlet 類實現(xiàn)了javax.servlet.Servlet 并提供了五個servlet方法的接口。它做的事情也很簡單:每次調用 init、service 或 destroy方法的時候,servlet就向控制口寫入方法名。service 方法也從ServletResponsec對象中獲得java.io.PrintWriter 對象,并發(fā)送字符串到瀏覽器。

      Listing 2.1.PrimitiveServlet.java

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

    public class PrimitiveServlet implements Servlet {
    public void init(ServletConfig config) throws ServletException {
    System.out.println("init");
    }

    public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
    System.out.println("from service");
    PrintWriter out = response.getWriter();
    out.println("Hello.Roses are
    red .");
    out.print("Violets are blue.");
    }

    public void destroy() {
    System.out.println("destroy");
    }

    public String getServletInfo() {
    return null;
    }

    public ServletConfig getServletConfig() {
    return null;
    }
    }
    Application 1

      現(xiàn)在,我們從 servlet容器的角度來看看 servlet 編程。一個功能健全的 servlet容器對于每個 servlet 的 HTTP請求會完成以下事情:

       1、當 servlet 第一次被調用的時候,加載了 servlet類并調用它的init方法(僅調用一次)

       2、響應每次請求的時候 ,構建一個javax.servlet.ServletRequest 和 javax.servlet.ServletResponse實例。
     
       3?、激活 servlet 的 service 方法,傳遞 ServletRequest 和 ServletResponse 對象。

       4、當servlet 類關閉的時候,調用 servlet 的destroy 方法,并卸載 servlet 類。

      發(fā)生在 servlet 容器內部的事就復雜多了。只是這個簡單的 servlet 容器的功能不很健全,所以,這它只能運行非常簡單的servelt ,并不能調用 servlet 的 init 和destroy 方法。然而,它也執(zhí)行了以下動作:

       1、等待 HTTP 請求。

       2、構建 ServletRequest 和 ServletResponse 對象

       3、如果請求的是一個staticResource,就會激活StaticResourceProcessor實例的 process方法,傳遞ServletRequest 和 ServletResponse 對象。

       4、如果請求的是一個servlet ,載入該類,并激活它的service 方法,傳遞ServletRequest 和ServletResponse 對象。注意:在這個servlet 容器,每當 servlet被請求的時候該類就被載入。

      在第一個應用程序中,servlet容器由六個類組成 。

       HttpServer1
       Request
       Response
       StaticResourceProcessor
       ServletProcessor1
       Constants

      這個程序的進入口(靜態(tài) main 方法)是HttpServer 類。這個方法創(chuàng)建了HttpServer實例,并調用它的await方法等待 HTTP 請示,然后創(chuàng)建一個 request 對象和 response對象,根據(jù)請求是否是staticResource還是 servlet 來分派它們到 StaticResourceProcessor實例或ServletProcessor實例。

      Constants 類包含 static find WEB_ROOT,它是從其他類引用的。 WEB_ROOT 指明 PrimitiveServlet 位置 和容器服務的staticResource。

      HttpServer1 實例等待 HTTP 請求,直到它收到一個 shutdown 命令。發(fā)布 shutdown命令和前文是一樣的。

      HttpServer1 類

      此應用程序內的 HttpServer1類 與前文簡單的 WEB 服務器應用程序中的HttpServer 十分相似。但是,此應用程序內的 HttpServer1 能服務靜態(tài)資源和 servlet。如果要請求一個靜態(tài)資源,請輸入以下 URL:
    http://machineName:port/staticResource 。如果要請求一個 servlet,請輸入以下 URL:

    http://machineName:port/servlet/servletClass

      如果您想在本地瀏覽器請求一個 PrimitiveServle servlet ,請輸入以下 URL:

    http://localhost:8080/servlet/PrimitiveServlet

      下面Listing 2.2類的await方法,是等待一個HTTP請求,直到一個發(fā)布shutdown命令。與前文的await 方法相似。

      Listing 2.2. HttpServer1 類的 await 方法

    public void await() {
    ServerSocket serverSocket = null;
    int port = 8080;

    try {
    serverSocket = new ServerSocket(port, 1,
    InetAddress.getByName("127.0.0.1"));
    }
    catch (IOException e) {
    e.printStackTrace();
    System.exit(1);
    }

    // 循環(huán),等待一個請求
    while (!shutdown) {
    Socket socket = null;
    InputStream input = null;
    OutputStream output = null;

    try {
    socket = serverSocket.accept();
    input = socket.getInputStream();
    output = socket.getOutputStream();

    // 創(chuàng)建請求對象并解析
    Request request = new Request(input);
    request.parse();

    // 創(chuàng)建回應對象
    Response response = new Response(output);
    response.setRequest(request);

    //檢測是否是 servlet 或靜態(tài)資源的請求
    //servlet 請求以 "/servlet/" 開始
    if (request.getUri().startsWith("/servlet/")) {
    ServletProcessor1 processor = new ServletProcessor1();
    processor.process(request, response);
    }
    else {
    StaticResourceProcessor processor =
    new StaticResourceProcessor();
    processor.process(request, response);
    }

    // 關閉socket
    socket.close();

    //檢測是否前面的 URI 是一個 shutdown 命令
    shutdown = request.getUri().equals(SHUTDOWN_COMMAND);
    }
    catch (Exception e) {
    e.printStackTrace();
    System.exit(1);
    }
    }
    }

      此文 await 方法和前文的不同點就是,此文的 await 方法中的請求調度到StaticResourceProcessor 或 ervletProcessor 。

      如果 URI中包含 "/servlet/.",請求推進到后面,否則,請求傳遞到 StaticResourceProcessor 實例。
    Request 類

      Servlet service 方法接受 servlet 容器的 javax.servlet.ServletRequest 和javax.servlet.ServletResponse 實例。因此,容器必須構建 ServletRequest和ServletResponse對象,然后將其傳遞到正在被服務的service 方法。

      ex02.pyrmont.Request 類代表一個請求對象傳遞到 service 方法。同樣地,它必須實現(xiàn) javax.servlet.ServletRequest 接口。這個類必須提供接口內所有方法的實現(xiàn)。這里盡量簡化它并只實現(xiàn)幾個方法。要編譯 Request 類的話,必須提供這些方法的空實現(xiàn)。再來看看 request 類,內部所有需要返回一個對象實例都返回null,如下:

    public Object getAttribute(String attribute) {
    return null;
    }

    public Enumeration getAttributeNames() {
    return null;
    }

    public String getRealPath(String path) {
    return null;
    }

      另外,request 類仍需有前文有介紹的 parse 和getUri 方法。

      Response 類

      response 類實現(xiàn) javax.servlet.ServletResponse,同樣,該類也必須提供接口內所有方法的實現(xiàn)。類似于 Request 類,除 getWriter 方法外,其他方法的實現(xiàn)都為空。

    public PrintWriter getWriter() {
    // autoflush is true, println() will flush,
    // but print() will not.
    writer = new PrintWriter(output, true);
    return writer;

    }

      PrintWriter 類構建器的第二個參數(shù)是一個代表是否啟用 autoflush 布爾值 ,如果為真,所有調用println 方法都 flush 輸出。而 print 調用則不 flush 輸出。因此,如果在servelt 的service 方法的最后一行調用 print方法,則從瀏覽器上看不到此輸出 。這個不完整性在后面的應用程序內會有調整。
    response 類也包含有前文中介紹的 sendStaticResource方法。

      StaticResourceProcessor 類

      StaticResourceProcessor 類用于服務靜態(tài)資源的請求。它唯一的方法是 process。

      Listing 2.3.StaticResourceProcessor 類的 process方法。

    public void process(Request request, Response response) {
    try {
    response.sendStaticResource();
    }
    catch (IOException e) {
    e.printStackTrace();
    }
    }

      process 方法接受兩個參數(shù):Request 和 Response 實例。它僅僅是調用 response 類的sendStaticResource 方法。
    主站蜘蛛池模板: 色老头永久免费网站| 全黄A免费一级毛片| 亚洲美女aⅴ久久久91| 亚洲性69影院在线观看| 亚洲中文精品久久久久久不卡| 春暖花开亚洲性无区一区二区| 国产乱子伦精品免费视频| 亚洲免费福利视频| 亚洲精品91在线| 一区二区3区免费视频| 四虎最新永久免费视频| 亚洲性色高清完整版在线观看| 国产成人精品免费视频大| 亚洲一区二区三区无码国产| 一级视频在线免费观看| 曰韩亚洲av人人夜夜澡人人爽| 亚洲国产精品综合福利专区| 无码国产精品一区二区免费式直播| 免费播放春色aⅴ视频| 久久狠狠爱亚洲综合影院| 成人毛片免费观看视频| 亚洲αv久久久噜噜噜噜噜| 国产精品亚洲专一区二区三区| 91久久精品国产免费直播| 亚洲人成www在线播放| 精品成在人线AV无码免费看 | 免费成人午夜视频| 一区二区免费电影| 亚洲av片劲爆在线观看| 久久久久国色AV免费观看| 亚洲一区二区在线视频| 丁香花在线视频观看免费| 四虎影库久免费视频| 亚洲日韩精品无码专区加勒比| 91精品免费观看| 亚洲av无码潮喷在线观看| 一二三四免费观看在线电影| 亚洲宅男天堂a在线| 免费成人av电影| 99爱在线精品免费观看| 亚洲看片无码在线视频|