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
對象或容器中已經創建的對象。