第2章 The servlet Interface
所有Servlet實現同一接口:Servlet,它有兩個直接的子類:GenericServlet和HttpServlet.
2.1 Request Handle method
基本的Servlet使用service()方法處理請求,因為可能有多個客戶的請求在service()中工作,所以開發者必須要考慮到并發的情況。
SRV.2.1.1 HTTP Specific Request Handling Methods
HttpServlet定義了以下7個方法:
-
doGet for handling HTTP GET requests
-
doPost for handling HTTP POST requests
-
doPut for handling HTTP PUT requests
-
doDelete for handling HTTP DELETE requests
-
doHead for handling HTTP HEAD requests
-
doOptions for handling HTTP OPTIONS requests
-
doTrace for handling HTTP TRACE requests
SRV.2.1.2 Additional Methods
??? 關于Http的幾個附加命令HEAD,DELETE,PUT,OPTIONS,TRACE。
SRV.2.1.3 Conditional GET Support
這個”Conditional GET“指的是這樣的請求:只有所請求的資源在一個特定時間之后被修改過,才被發送給客戶端。
HttpServlet里的getLastModified()方法提供了這方面的支持。
SRV.2.2 Number of Instances
??? 在2.4之前的版本中,Servlet有兩種方式:
??? 第一種方式是對于一個Servlet,只有一個實例,這個實例可以同時服務多個用戶,這是默認的。
??? 另一種方式是一個Servlet的實例只能服務一個客戶,這樣就需要一個Servlet的Pool,當多個用戶連接時,需要建立多個Servlet實例。這種方式需要Servlet實現SingleThreadModel接口。
??? 以上兩種方式的比較:第一種方式需要考慮同步問題(因為一個Servlet的實例服務多個用戶,Servlet中的數據成員需要同步),第二種方式不需要考慮同步問題。
???
SRV.2.3 Servlet Life Cycle
??? 1.載入:???
??? 應用服務器可能在啟動時載入Servlet或者在第一個請求到來時延遲加載,載入的方式也是使用類裝載器,和普通的Java Object沒有什么區別。
??? 2.初始化:
??? 初始化時可能遇到錯誤,這時會拋出ServletException或者UnaviliableException異常
??? 3.多線程:
??? 需要注意的一點是,最好不要對service()方法進行synchronize修飾。這樣的話就不能使用線程池,而必須對request序列化
??? 4.處理請求時的錯誤處理:
???
如果在這時發生異常,可以發送UnavailableException或者ServletException,如果發送了
ServletException,服務器必須要想辦法清除request。如果發送了UnavailableException,有兩種選擇,如果是永
久的的無效,需要調用destroy(),并摧毀Servlet,如果這時客戶端訪問此Servlet,它將會收到404錯誤。如果是臨時的無效,容器需
要拒絕任何到此Servlet的請求,并且返回503錯誤
?? 5.線程安全的話題
??? request和response這兩個對象不是線程安全的,所以不要在service()方法外面使用它們,它們的引用不應該傳給另一個線程中的對象,如果一定要訪問它們,必須對使用這兩個對象的代碼進行同步。
??? 6.服務的結束
?? Servlet容器并不需要一直保持一個Servlet處于運行狀態,在釋放一個servlet時,會調用destroy方法,當調用destroy方法之前,容器會一直等到所有的線程都完成了在service()方法中的工作。
第3章 Servlet Context
SRV.3.1 Introduction to the ServletContext Interface
Servlet Context,從Servlet的角度來看,可以理解為它所屬Web應用程序,ServletContext是一個接口,Servlet容器的提供商必須要實現這個接口。
ServletContext能做什么呢?它可以把事件記錄到日志中,獲得資源的URL,還可以利用ServletContext存放一些所有Servlet都能共享的數據。
ServletContext有一個路徑,例如http://www.mycorp.com/catalog,這里的cataqlog就是ServletContext的路徑,所有的對catalog的請求都會關聯到這個ServletContext.
SRV.3.2 Scope of a ServletContext Interface
在Servlet容器中,每個ServletContext通常只有一個實例。當Web容器是分布式的部署在多臺機器上時,那一個ServletContext在每個JVM上都有一個實例。
在Servlet容器中,但沒有部署的Servlet也是允許的,這種Servlet屬于一個缺省的ServletContext,這種缺省的ServletContext不能被分布到多個JVM上。
SRV.3.3 Initialization Parameters
在ServletContext接口中,有兩個方法可以用來獲得初始化參數:
? getInitParameter
? getInitParameterNames
SRV.3.4 Context Attributes
在ServletContext中,有4個方法可以用來設置和管理ServletContext的屬性:
? setAttribute
? getAttribute
? getAttributeNames
? removeAttribute
SRV.3.4.1 Context Attributes in a Distributed Container
ServletContext中的屬性只在本地的JVM中有效,不能被分布式環境中運行于其它JVM中的Servlet訪問,如果需要在分布式環境中共享數據,可以把數據存放在Session,數據庫或EJB中。
SRV.3.5 Resources
資源指的是在Web應用程序中的一些靜態的內容,如靜態HTML頁面,圖片等等。ServletContext提供了兩個方法來訪問這些資源:
? getResource
? getResourceAsStream
這兩個方法都接受一個String型參數,它指定了一個以"/"開頭的相對于這個ServletContext的資源路徑。資源可以放在同一服務器上,或者不同服務器上,或者在一個Web應用程序的WAR包中。
需要注意的是,這兩個方法不能用來獲取動態內容,如果我們用這兩個方法去取一個JSP頁面,返回的將是JSP頁面的源代碼。
getResourcePaths(String path)方法可以用來獲取一個資源列表。
SRV.3.6 Multiple Hosts and Servlet Contexts
Web服務器可能支持多個域名分享一個IP地址,這種配置叫做“虛擬主機”。在這種情況下,每個虛擬主機必須要有自己的ServletContext,而不能共享一個ServletContext。
SRV.3.7 Reloading Considerations
所有的Servlet和它們引用的類必須都處于一個類裝載器范圍內。
SRV.3.7.1 Temporary Working Directories
每一個ServletContext都需要一個臨時目錄,并且通過
javax.servlet.context.tempdir屬性指定。Servlet容器不需要管理這個臨時路徑的內容,但是要確保一個
ServletContext的臨時目錄對其他的ServletContext是不可見的。