1.? Request Response 對象起到了服務器與客戶機之間的信息傳遞作用。

? ??Request 對象用于接收客戶端瀏覽器提交的數據,而 Response 對象的功能則是將服務器端的數據發送到客戶端瀏覽器。

? ?Request 對象

l?????? ???? 從瀏覽器端取得數據的方法

l?????? ????Request.QueryString 集合讀取表單 GET 方法數據 ?????

l?????? ????Request.Form 集合讀取表單 POST 方法數據 ?????

l?????? ????Request.ServerVariables 集合讀取服務器端環境變量

?

2. 為什么 servlet jsp 中可以直接使用 req res 對象?

自己的理解:(不一定正確,有待學習和理解)

servlet 容器類負責貞聽請求,如果捕獲到請求,請創建 req res 對象,然后激活 service ()方法,(或者,如果是 get 請求,激活 doGet ()方法;如果是 post ,則激活 doPost ()方法),并且同時也把 req res 對象傳遞給了 service ()方法(或者是相應的 doGet() doPost() 方法);

也就是說 servlet 容器類貞聽到請求后已經自動創建 req res 對象,并傳遞給 service ()方法了,所以自己編碼實現 servlet service ()方法時候,直接使用 req res 對象就可以,因為 service ()方法(由 service 方法根據請求方式再調用相應的 doGet ()和 doPost ()方法) 是容器負責自動調用的,調用的同時也實現的 req res 的傳參。 Ok !!

?

問題:迫切需要查看 tomcat javax.servlet.Servlet 接口實現的類來驗證自己的理解;

?

參考資料:

Servlet 容器工作原理(一)(二)(三)(四)

http://www.linuxmine.com/45398.html

注釋:這是一個通過給出簡單實現 servlet 容器的源代碼的方式來闡述 servlet 容器( tomcat )工作原理的好資料。

關鍵內容摘要:

編者注 : 本文和同系列的前面一文“基于 Java Web 服務器工作原理”,都摘自“ Tomcat 運行內幕”一書(一本有關 Tomcat 的教程)。在閱讀本文前,最好先閱讀前文,以鞏固基礎信息。在此,將介紹如何建立兩個 servlet 容器。 隨附本書的應用程序可以下載 ,如果您有興趣,可以在近段時間內到 作者網站 下載。

?

   本文介紹一個簡單 servlet 容器的基本原理。這個 servlet 容器都處理簡單的 servlet staticResource 。復雜一些的 servlet 會超出這些容器的容量,您可以從 TOMCAT? 運行內幕 一書學習創建復雜的 servlet 容器。

?

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

?

   javax.servlet.Servlet 接口

?

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

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

l???????? public void init(ServletConfig config) throws ServletException

l???????? public void service(ServletRequest request, ServletResponse response)? throws ServletException, java.io.IOException

l???????? public void destroy()

l???????? public ServletConfig getServletConfig()

l???????? public java.lang.String getServletInfo()

?

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

?

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

?

一個功能健全的 servlet 容器對于每個 servlet HTTP 請求會完成以下事情:

?

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

l???????? 響應每次請求的時候 ,構建一個 javax.servlet.ServletRequest javax.servlet.ServletResponse 實例。

l???????? 激活 servlet service 方法,傳遞 ServletRequest ServletResponse 對象。

l???????? servlet 類關閉的時候,調用 servlet destroy 方法,并卸載 servlet 類。

?

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

?

l???????? 等待 ? HTTP 請求。

l???????? 構建 ServletRequest ? ServletResponse 對象 ?

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

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

Servlet 容器的關鍵工作流程 HttpServer1 類的 await 方法
在這個應用程序中, servlet 容器由六個類組成

• HttpServer1
• Request
• Response
• StaticResourceProcessor
• ServletProcessor1
• Constants

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

代碼如下:  
    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);
     }
  
   // 循環,等待一個請求
   while (!shutdown) {
   Socket socket     = null;
   InputStream input   = null;
   OutputStream output = null;
  
   try {
   socket = serverSocket.accept();// 貞聽用戶請求;
   input   = socket.getInputStream();
   output = socket.getOutputStream();
  
   // 如果捕獲用戶請求,則創建請求對象并解析
   Request request = new Request(input);
   request.parse();
  
   // 創建回應對象
   Response response = new Response(output);
   response.setRequest(request);
  
   // 檢測是否是 servlet 或靜態資源的請求
   //servlet 請求以 "/servlet/" 開始
   if (request.getUri().startsWith("/servlet/")) {
   ServletProcessor1 processor = new ServletProcessor1();

// 激活 process req res )方法,并同時把 req res 實例傳遞給 process ()方法;

// tomcat 中,激活的是 service req res )方法(或者相應的 doGet doPost 方法)
   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);
       }
     }
   }
   如果 URI 中包含 "/servlet/." ,請求推進到后面,否則,請求傳遞到 StaticResourceProcessor 實例。

Ok

?

3. 如何理解內置的含義?(不一定正確,有待學習和理解)

http://topic.csdn.net/t/20060211/20/4551196.html

問:

如何深入理解內置對象 ?
?
最好是在實現原理層次上

答:

tomcat 的體系中,有個 jsp ? parser ,它的作用是把 jsp 頁面 parse java 程序( servlet ),然后再運行 parse 出來的 servlet ,由此可見, 9 個內置對象就是 jsp ? parser 在根據 jsp 頁面生成 servlet 的時候自動創建的 java 對象或容器中已經創建的對象。