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