摘要:初始化的錯誤處理在初始化期間,實例可能通過拋出或者異常表明它不能進行有效服務。每一個請求由類型的對象代表,而使用回應該請求。在請求的情況下,容器必須提供代表請求和回應的和的具體實現。表明不能對請求進行處理,可能是暫時的,也可能是永久的。
servlet詳解
Servlet有良好的生存期的定義,包括如何加載、實例化、初始化、處理客戶端請求以及如何被移除。這個生存期由javax.Servlet.Servlet接口的init,service和destroy方法表達。
1、加載和實例化
容器負責加載和實例化一個Servlet。實例化和加載可以發生在引擎啟動的時候,也可以推遲到容器需要該Servlet為客戶請求服務的時候。
首先容器必須先定位Servlet類,在必要的情況下,容器使用通常的Java類加載工具加載該Servlet,可能是從本機文件系統,也可以是從遠程文件系統甚至其它的網絡服務。容器加載Servlet類以后,它會實例化該類的一個實例。需要注意的是可能會實例化多個實例,例如一個Servlet類因為有不同的初始參數而有多個定義,或者Servlet實現SingleThreadModel而導致容器為之生成一個實例池。
2、初始化
Servlet加載并實例化后,容器必須在它能夠處理客戶端請求前初始化它。初始化的過程主要是讀取永久的配置信息,昂貴資源(例如JDBC連接)以及其它僅僅需要執行一次的任務。通過調用它的init方法并給它傳遞唯一的一個(每個Servlet定義一個)ServletConfig對象完成這個過程。給它傳遞的這個配置對象允許Servlet訪問容器的配置信息中的名稱-值對(name-value)初始化參數。這個配置對象同時給Servlet提供了訪問實現了ServletContext接口的具體對象的方法,該對象描述了Servlet的運行環境。
2.1初始化的錯誤處理
在初始化期間,Servlet實例可能通過拋出UnavailableException 或者 ServletException異常表明它不能進行有效服務。如果一個Servlet拋出一個這樣的異常,它將不會被置入有效服務并且應該被容器立即釋放。在此情況下destroy方法不會被調用因為初始化沒有成功完成。在失敗的實例被釋放后,容器可能在任何時候實例化一個新的實例,對這個規則的唯一例外是如果失敗的Servlet拋出的異常是UnavailableException并且該異常指出了最小的無效時間,那么容器就會至少等待該時間指明的時限才會重新試圖創建一個新的實例。
2.2、工具因素
當工具(注:根據筆者的理解,這個工具可能是應用服務器的某些檢查工具,通常是驗證應用的合法性和完整性)加載和內省(introspect)一個web應用時,它可能加載和內省該應用中的類,這個行為將觸發那些類的靜態初始方法被執行,因此,開發者不能假定只要當Servlet的init方法被調用后它才處于活動容器運行狀態(active container runtime)。作為一個例子,這意味著Servlet不能在它的靜態(類)初始化方法被調用時試圖建立數據庫連接或者連接EJB容器。
3、處理請求
在Servlet被適當地初始化后,容器就可以使用它去處理請求了。每一個請求由ServletRequest類型的對象代表,而Servlet使用ServletResponse回應該請求。這些對象被作為service方法的參數傳遞給Servlet。在HTTP請求的情況下,容器必須提供代表請求和回應的HttpServletRequest和HttpServletResponse的具體實現。需要注意的是容器可能會創建一個Servlet實例并將之放入等待服務的狀態,但是這個實例在它的生存期中可能根本沒有處理過任何請求。
3.1、多線程問題
容器可能同時將多個客戶端的請求發送給一個實例的service方法,這也就意味著開發者必須確保編寫的Servlet可以處理并發問題。如果開發者想防止這種缺省的行為,那么他可以讓他編寫的Servlet實現SingleThreadModel。實現這個類可以保證一次只會有一個線程在執行service方法并且一次性執行完。容器可以通過將請求排隊或者維護一個Servlet實例池滿足這一點。如果Servlet是分布式應用的一部分,那么,那么容器可能在該應用分布的每個JVM中都維護一個實例池。如果開發者使用synchronized關鍵字定義service 方法(或者是doGet和doPost),容器將排隊處理請求,這是由底層的java運行時系統要求的。我們強烈推薦開發者不要同步service方法或者HTTPServlet的諸如doGet和doPost這樣的服務方法。
3.2、處理請求中的異常
Servlet在對請求進行服務的時候有可能拋出ServletException或者UnavailableException異常。ServletException表明在處理請求的過程中發生了錯誤容器應該使用合適的方法清除該請求。UnavailableException表明Servlet不能對請求進行處理,可能是暫時的,也可能是永久的。如果UnavailableException指明是永久性的,那么容器必須將Servlet從服務中移除,調用它的destroy方法并釋放它的實例。如果指明是暫時的,那么容器可以選擇在異常信息里面指明的這個暫時無法服務的時間段里面不向它發送任何請求。在這個時間段里面被被拒絕的請求必須使用SERVICE_UNAVAILABLE (503)返回狀態進行響應并且應該攜帶稍后重試(Retry-After)的響應頭表明不能服務只是暫時的。容器也可以選擇不對暫時性和永久性的不可用進行區分而全部當作永久性的并移除拋出異常的Servlet。
3.3線程安全
開發者應該注意容器實現的請求和響應對象(注:即容器實現的HttpServletRequest和HttpServletResponese)沒有被保證是線程安全的,這就意味著他們只能在請求處理線程的范圍內被使用,這些對象不能被其它執行線程所引用,因為引用的行為是不確定的。
4、服務結束
容器沒有被要求將一個加載的Servlet保存多長時間,因此一個Servlet實例可能只在容器中存活了幾毫秒,當然也可能是其它更長的任意時間(但是肯定會短于容器的生存期)當容器決定將之移除時(原因可能是保存內存資源或者自己被關閉),那么它必須允許Servlet釋放它正在使用的任何資源并保存任何永久狀態(這個過程通過調用destroy方法達到)。容器在能夠調用destroy方法前,它必須允許那些正在service方法中執行的線程執行完或者在服務器定義的一段時間內執行(這個時間段在容器調用destroy之前)。一旦destroy方法被調用,容器就不會再向該實例發送任何請求。如果容器需要再使用該Servlet,它必須創建新的實例。destroy方法完成后,容器必須釋放Servlet實例以便它能夠被垃圾回收。
5.多種Servlet接口介紹
Servlet接口:
public interface Servlet
它的生命周期由javax.Servlet.Servlet接口定義。當你在寫Servlet的時候必須直接或間接的實現這個接口。一般趨向于間接實現:通過從javax.Servlet.GenericServlet或javax.Servlet.http.HttpServlet派生。在實現Servlet接口時必須實現它的五個方法:
1.init():
public void init(ServletConfig config) throws ServletException
一旦對Servlet實例化后,容器就調用此方法。容器把一個ServletConfig對象傳統給此方法,這樣Servlet的實例就可以把與容器相關的配置數據保存起來供以后使用。如果此方法沒有正常結束就會拋出一個ServletException。一旦拋出該異常,Servlet就不再執行,而隨后對它的調用會導致容器對它重新載入并再次運行此方法。接口規定對任何Servlet實例,此方法只能被調用一次,在任何請求傳遞給Servlet之前,此方法可以在不拋出異常的情況下運行完畢。
2.service():
public void service(ServletRequest req,ServletResponse res) throws ServletException,IOException
只有成功初始化后此方法才能被調用處理用戶請求。前一個參數提供訪問初始請求數據的方法和字段,后一個提供Servlet構造響應的方法。
3.destroy():
public void destroy()
容器可以在任何時候終止Servlet服務。容器調用此方法前必須給service()線程足夠時間來結束執行,因此接口規定當service()正在執行時destroy()不被執行。
4.getServletConfig():
public ServletConfig getServletConfig()
在Servlet初始化時,容器傳遞進來一個ServletConfig對象并保存在Servlet實例中,該對象允許訪問兩項內容:初始化參數和ServletContext對象,前者通常由容器在文件中指定,允許在運行時向sevrlet傳遞有關調度信息,后者為Servlet提供有關容器的信息。此方法可以讓Servlet在任何時候獲得該對象及配置信息。
5.getServletInfo():
public String getServletInfo()
此方法返回一個String對象,該對象包含Servlet的信息,例如開發者、創建日期、描述信息等。該方法也可用于容器。
GenericServlet類
Public abstract class GenericServlet implants Servlet,ServletConfig,Serializable
此類提供了Servlet接口的基本實現部分,其service()方法被申明為abstract,因此需要被派生。init(ServletConfig conf)方法把ServletConfig對象存儲在一個private transient(私有臨時)實例變量里,getServletConfig()方法返回指向本對象的指針,如果你重載此方法,將不能使用getServletConfig來獲得ServletConfig對象,如果確實想重載,記住要包含對super.config的調用。2.1版的API提供一個重載的沒有參數的init()方法。現在在init(ServletConfig)方法結束時有一個對init()的調用,盡管目前它是空的。2.1版API里面,此類實現了ServletConfig接口,這使得開發者不用獲得ServletConfig對象情況下直接調用ServletConfig的方法,這些方法是:getInitParameter(),getInitParameterNames(),getServletContext。此類還包含兩個寫日志的方法,它們實際上調用的是ServletContext上的對應方法。log(String msg)方法將Servlet的名稱和msg參數寫到容器的日志中,log(String msg,Throwable cause)除了包含Servlet外還包含一個異常。
HttpServlet類
該類擴展了GenericServlet類并對Servlet接口提供了與HTTP更相關的實現。
service():
protected void service(HttpServletRequest req,HttpServletResponse res) throws ServletException,IOException
public void service(HttpServletRequest req,HttpServletResponse res)throws ServletException,IOException
該方法作為HTTP請求的分發器,這個方法在任何時候都不能被重載。當請求到來時,service()方法決定請求的類型(GET,POST,HEAD,OPTIONS,DELETE,PUT,TRACE),并把請求分發給相應的處理方法(doGet(),doPost(),doHead(),doOptions(),doDelete(),doPut(),doTrace())每個do 方法具有和第一個service()相同的形式。為了響應特定類型的HTTP請求,我們必須重載相應的do方法。如果Servlet收到一個HTTP請求而你沒有重載相應的do方法,它就返回一個說明此方法對本資源不可用的標準HTTP錯誤。
getLatModified():
protected long getLastModified(HttpServletRequest req)
該方法返回以毫秒為單位的的自GMT時間1970年1月1日0時0分0秒依賴的最近一次修改Servlet的時間,缺省是返回一個負數表示時間未知。當處理GET請求時,調用此方法可以知道Servlet的最近修改時間,服務器就可決定是否把結果從緩存中去掉。
HttpServletRequest接口
public interface HttpServletRequest extends ServletRequest
所有實現此接口的對象(例如從Servlet容器傳遞的HTTP請求對象)都能讓Servlet通過自己的方法訪問所有請求的數據。下面是一些用來獲取表單數據的基本方法。
getParameter()
public String getParameter(String key)
此方法試圖將根據查詢串中的關鍵字定位對應的參數并返回其值。如果有多個值則返回列表中的第一個值。如果請求信息中沒有指定參數,則返回null。
getParametervalues():
public String[] getParametervalues(String key)
如果一個參數可以返回多個值,比如復選框集合,則可以用此方法獲得對應參數的所有值。如果請求信息中沒有指定參數,則返回null。
GetParameterNames():
Public Enumeration getParameterNames()
此方法返回一個Enumeration對象,包含對應請求的所有參數名字列表。
HttpServletResponse接口
public interface HttpServletResponse extends ServletResponse
Servlet容器提供一個實現該接口的對象并通過service()方法將它傳遞給Servlet。通過此對象及其方法,Servlet可以修改響應頭并返回結果。
setContentType():
public void setContentType(String type)
在給調用者發回響應前,必須用此方法來設置HTTP響應的MIME類型。可以是任何有效的MIME類型,當給瀏覽器返回HTML是就是”text/html”類型。
getWriter():
public PrintWriter getWriter()throws IOException
此方法將返回PrintWriter對象,把Servlet的結果作為文本返回給調用者。PrintWriter對象自動把Java內部的UniCode編碼字符轉換成正確的編碼以使客戶端能夠閱讀。
getOutputStream():
public ServletOutputStream getOutputStream() throws IOException
此方法返回ServletOutputStream對象,它是java.io.OutputStream的一個子類。此對象向客戶發送二進制數據。
setHeader():
public void setHeader(String name,String value)
此方法用來設置送回給客戶的HTTP響應頭。有一些快捷的方法用來改變某些常用的響應頭,但有時也需要直接調用此方法。
編譯條件
需要從http://java.sun.com/products/Servlet/ 獲得一份JSDK的拷貝,并把Servlet.jar移動到JDK安裝目錄下的jrelibext目錄下。如果是JDK1.1,則移動到lib下,并在CLASSPATH中加入Servlet.jar的絕對路徑。
運行條件
需要Apache Jserv,Jrun Servlet Exec,Java Web Server,Weblogic,WebSphere,Tomcat,Resin等Servlet服務器端程序。
Java代碼
1.import java.io.*;
2.import javax.servlet.*;
3.import javax.servlet.http.*;
4.public class HelloWorld extends HttpServlet {
5. public void doGet(HttpServletRequest request, HttpServletResponse response)throws IOException, ServletException
6.{ response.setContentType("text/html");
7. PrintWriter out = response.getWriter();
8. out.println("");
9. out.println("
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/64120.html
摘要:但是這樣依然有一個問題,考慮以下場景有一個容器,線程池大小。這個時候工程師發現了問題,擴展了線程池大小到,但是負載依然持續走高,現在有個到,依然無法響應。你可以修改的線程池大小,把它和比較結果來驗證這一結論。 Github地址 相關系列文章: Servlet 3.1 Async IO分析 Spring MVC異步處理的幾種方式 Servlet 3.0 開始提供了AsyncConte...
摘要:一對象在的配置文件中,可以使用一個或多個標簽為配置一些初始化參數。進而,程序員通過對象就可以得到當前的初始化參數信息。對象通常也被稱之為域對象。 一、ServletConfig對象 在Servlet的配置文件中,可以使用一個或多個標簽為servlet配置一些初始化參數。(配置在某個servlet標簽或者整個web-app下) 當servlet配置了初始化參數后,web容器在創建se...
摘要:的版本增加了對事件監聽程序的支持,事件監聽程序在建立修改和刪除會話或環境時得到通知。元素指出事件監聽程序類。過濾器配置將一個名字與一個實現接口的類相關聯。 1.簡介 web.xml文件是Java web項目中的一個配置文件,主要用于配置歡迎頁、Filter、Listener、Servlet等,但并不是必須的,一個java web項目沒有web.xml文件照樣能跑起來。Tomcat容器/...
閱讀 2312·2021-11-17 09:33
閱讀 843·2021-10-13 09:40
閱讀 573·2019-08-30 15:54
閱讀 778·2019-08-29 15:38
閱讀 2417·2019-08-28 18:15
閱讀 2475·2019-08-26 13:38
閱讀 1841·2019-08-26 13:36
閱讀 2129·2019-08-26 11:36