
Servlet容器
Servlet規定的,相應客戶(hù)請求訪(fǎng)問(wèn)特定Servlet流程如下:
1.客戶(hù)端發(fā)出請求。
2.Servlet容器接收客戶(hù)請求解析。
3.Servlet容器創(chuàng )建一個(gè)ServletRequest對象。
其中包含客戶(hù)請求信息及其他關(guān)于客戶(hù)的信息如請求頭,請求正文,客戶(hù)機的IP等。
4.容器創(chuàng )建一個(gè)ServletResponse對象。
5.容器調用客戶(hù)請求的Servlet的service方法,并且把ServletRequest和ServletResponse作為參數傳入。
6.Servlet從客戶(hù)參數中獲得客戶(hù)請求信息。
7.Servlet利用ServletResponse對象來(lái)生產(chǎn)相應結果。
8.Servlet容器把Servlet生成的結果發(fā)給客戶(hù)。

Tomcat工作模式
① 獨立的Servlet容器
Tomcat作為獨立的Web服務(wù)器來(lái)單獨運行。
② 其他Web服務(wù)器進(jìn)程內的Servlet容器
這種模式下,Tomcat與Web服務(wù)器插件和Servlet容器組件兩部分。Web服務(wù)器插件在其他Web服務(wù)器進(jìn)程的內部地址空間啟動(dòng)一個(gè)Java虛擬機,Servlet容器組件在此Java虛擬機中運行。如有Servlet請求,Web服務(wù)器插件獲得此請求并轉發(fā)給Servlet容器(JNI通信,Java本地調用接口)。
3 其他Web服務(wù)器進(jìn)程外的Servlet容器
與上面類(lèi)似,只是在Web服務(wù)器外部地址,啟動(dòng)一個(gè)Java虛擬機進(jìn)程,轉發(fā)用IPC通信機制,兩個(gè)進(jìn)程之間通信的一種機制。
Servlet容器
Servlet是Java WEB應用中最核心的組件,最常用:
1.請求對象ServletRequest和HttpServletResponse
2.響應對象ServletResponse、HttpServletResponse
3.Servlet配置對象,ServletConfig,容器初始化一個(gè)Servlet時(shí),會(huì )向他提供一個(gè)ServletConfig對象,Servlet通過(guò)該對象來(lái)獲取初始化參數信息以及ServletContext對象。
4.ServletContext對象:通過(guò)它來(lái)訪(fǎng)問(wèn)容器為當前Web應用提供的各種資源
主要由兩個(gè)Java包組成,javax.servlet和javax.servlet.http前者定義了Servlet接口以及相關(guān)的通用接口和相關(guān)類(lèi),后者定義了與HTTP協(xié)議相關(guān)的。

Servlet接口
Servlet API的核心,所有的Servlet都必須實(shí)現這一接口,定義了5個(gè)方法,其中3個(gè)方法由容器來(lái)調用,容器會(huì )在Servlet生命周期的不同階段調用特定方法。
1.Init
2.Service(ServletRequest req,ServletResponse res),響應客戶(hù)請求,訪(fǎng)問(wèn)特定servlet對象時(shí),調用service方法
3.destory():負責釋放Servlet對象占用的資源,當Servlet對象結束生命周期時(shí),容器會(huì )調用此方法
4.getServletConfig:返回一個(gè)ServletConfig對象。所有的servlet
5.getServletInfo:返回一個(gè)字符串,返回Servlet創(chuàng )建者,版本,版權信息等。

GenericServlet

ServletConfig
<servlet>
<servlet-name>....</servlet-name>
<servlet-class>.....</servlet-class>
<init-param>
<param-name>....<param-name>
<param-value>....<param-value>
</init-param>
</servlet>
<servlet-mapping>
</servlet-mapping>
Servlet
ServiceConfig還有一個(gè)當前的ServletContext對象關(guān)聯(lián)的API.
從一個(gè)servlet被實(shí)例化后,對任何客戶(hù)端在任何時(shí)候訪(fǎng)問(wèn)有效,但僅對本servlet有效,一個(gè)servlet的ServletConfig對象不能被另一個(gè)servlet訪(fǎng)問(wèn)。
getInitParameter()/getInitParameter(String name),用來(lái)獲得初始化參數,getServletContext
getServletName:返回SERVLET的名字即web xml中相應servlet元素<servlet-name>元素的值:
HttpServlet抽象類(lèi)
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
String method = req.getMethod();
if (method.equals(METHOD_GET)) {
long lastModified = getLastModified(req);
if (lastModified == -1) {
// servlet doesn't support if-modified-since, no reason
// to go through further expensive logic
doGet(req, resp);
} else {
long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
if (ifModifiedSince < (lastModified / 1000 * 1000)) {
// If the servlet mod time is later, call doGet()
// Round down to the nearest second for a proper compare
// A ifModifiedSince of -1 will always be less
maybeSetLastModified(resp, lastModified);
doGet(req, resp);
} else {
resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
}
}
long lastModified = getLastModified(req);
maybeSetLastModified(resp, lastModified);
doHead(req, resp);
} else if (method.equals(METHOD_POST)) {
doPost(req, resp);
} else if (method.equals(METHOD_PUT)) {
doPut(req, resp);
} else if (method.equals(METHOD_DELETE)) {
doDelete(req, resp);
} else if (method.equals(METHOD_OPTIONS)) {
doOptions(req,resp);
} else if (method.equals(METHOD_TRACE)) {
doTrace(req,resp);
} else {
//
// Note that this means NO servlet supports whatever
// method was requested, anywhere on this server.
//
String errMsg = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[1];
errArgs[0] = method;
errMsg = MessageFormat.format(errMsg, errArgs);
resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
}
}
ServletRequest 與HttpServletRequest
前者表示客戶(hù)端請求參數,用它可以讀取客戶(hù)端請求數據的方法,比如getContentType、getLocalPort等。
后者是前者的子接口,它提供了讀取HTTP請求中相關(guān)信息的方法,比如getMethod,getQueryString,HTTP請求中的查詢(xún)字符串,?后面的內容。
本來(lái),我們得自己去解析HTTP請求,然后做出回應,現在根據sun的servlet API來(lái)構建Servlet,則無(wú)需實(shí)現費力地解析如HTTP請求,這都有Servlet代勞,并封轉為HttpServletRequest對象,Servlet只需要調用getXXX方法。
ServletResponse和HttpServletResponse
前者用來(lái)生產(chǎn)相應結果,它有一系列設置響應信息的setXXX方法,默認為text/plain,存文本,servlet通過(guò)servletResponse產(chǎn)生HTTP相應的正文部分。二進(jìn)制用Servlet的getOutPutStream方法返回一個(gè)ServletOutputStream對象來(lái)輸出二進(jìn)制數據,getWrte方法返回一個(gè)PrintWrite對象,用來(lái)返回字符串形式的正為。
后者是前者的子接口,通過(guò)它來(lái)設置HTTP響應頭,向客戶(hù)端寫(xiě)cookie等,addHeader。addCookie。
另外,它還有一個(gè)靜態(tài)的狀態(tài)常量。
ServletContext
是Servlet與Servlet容器的接口,容器啟動(dòng)一個(gè)Web應用時(shí),都為之創(chuàng )建一個(gè)唯一ServletContext對象,管理訪(fǎng)問(wèn)容器的各種資源,6個(gè)方法:
1.在web應用范圍內共享數據的方法,setAttribute,getAttribute
2.訪(fǎng)問(wèn)當前Web應用的資源
3.訪(fǎng)問(wèn)Servlet容器中的其他Web應用。ServletContext getContext(java.lang.String uripath)
4.訪(fǎng)問(wèn)服務(wù)器端的文件系統資源,getRealPath,getResource
5.輸出日志
6.訪(fǎng)問(wèn)容器相關(guān)信息
ServletContext:對任何servlet,任何人在任何時(shí)間都有效,這才是真正全局的對象。
<web-app>
.................
<init-param>
<param-name>charset</param-name>
<param-value>GB2312</param-value>
</init-param>
.................
</web-app>

Java Web的生命周期與Servlet生命周期
1.Web應用:3階段,啟動(dòng)階段、運行階段、終止階段
a) 啟動(dòng):加載web.xml--------為web應用創(chuàng )建一個(gè)ServletContext對象-----初始化所有Filter-----對需要啟動(dòng)時(shí)就要初始化的Servlet初始化
b) 運行:最重要階段,這時(shí),所有Servlet處于待命階段,隨時(shí)響應請求,如果servlet未初始化,則先初始化,再調用servlet方法
c) 終止:銷(xiāo)毀處于運行狀態(tài)的servlet---銷(xiāo)毀運行階段的Filter-----銷(xiāo)毀所有WEB應用相關(guān)的對象,如ServletCCotext,并且釋放web應用占用的資源
2.Servlet生命周期:3個(gè)狀態(tài),初始化、運行、銷(xiāo)毀
A初始化 claa文件讀入內存------Servlet容器創(chuàng )建ServletConfig------包含了特別Servlet的初始化配置信息--------容器創(chuàng )建Servlet對象----調用Servlet對象的init(ServletConfig fig)
如果servlet被首次訪(fǎng)問(wèn),會(huì )初始化,如果servlet設置了<load-on-startup>元素,則容器啟動(dòng)servlet應用時(shí),就會(huì )初始化
B.運行階段 響應請求
C 銷(xiāo)毀:web應用終止時(shí),Servlet容器會(huì )調用所有servlet的destory方法,然后再銷(xiāo)毀這些servlet對象,另外,還銷(xiāo)毀與servlet關(guān)聯(lián)的ServletConfig。
3.ServletContext與Web應用范圍
ServletContext與Web應用有同樣的生命周期,Web應用范圍表示,由WEB應用的生命周期構成的時(shí)間段,WEB應用的生命周期內所有的Web組件集合,共享數據,可以在Wwb應用范圍內存取共享,這可以通過(guò)ServletContext對象來(lái)實(shí)現,這就是setAttribute和removeAttrinut、getAttribute等。
4.ServletContextListener監聽(tīng)器
監聽(tīng)ServletContext的生命周期,實(shí)際上就是監聽(tīng)Web應用的生命周期
contextInitialized、contextDestoryed事件,這可以用來(lái)實(shí)現初始化、銷(xiāo)毀的時(shí)候,一些持久化存儲(下載/上傳/圖像/。。。。)
過(guò)濾器
在一些web組件響應客戶(hù)請求過(guò)程中,可能都會(huì )完成一些相同的操作,比如,先檢查IP,可以使用過(guò)濾器:在wen組件被調用前,檢查serviceRequest對象,修改請求頭,和請求正文的內容,或者對請求進(jìn)行預處理操作;過(guò)濾器,能在wen組件被調用后檢查ServletResponse對象,修改響應頭和響應正文。
HTTP會(huì )話(huà)
會(huì )話(huà)管理:有些情況下,容器會(huì )把httpsession對象從內存中轉移到持久設備中,這可以確保重啟web應用后,能恢復重啟前的會(huì )話(huà)。
Tomcat目前包括兩種方式:
標準會(huì )話(huà)管理器:org.apache.catalina.session.StandardManager
持久會(huì )話(huà)管理器:org.......................................PresistentManager
前者:當Tomcat服務(wù)器終止或者web應用終止時(shí),會(huì )對被終止的web應用的httpsession對象進(jìn)行持久化,保存在文件中。Home/WORK/CATALINA/HOSTNAME/APPLICATIONNAME/sessions.ser。重啟時(shí),激活
后者:提供了更靈活的功能,它把存放httpsession對象的永久性存儲設備稱(chēng)為會(huì )話(huà)store:
ü 當tomcat關(guān)閉時(shí)或重啟(或單個(gè)web),會(huì )對httpsession持久化store中
ü 具有容錯功能,這時(shí)備份到會(huì )話(huà)store中,防止意外關(guān)閉
ü 靈活控制內存中的httpsession的數目
兩種實(shí)現:
FileStore,文件中
JDBCStore:數據庫中
會(huì )話(huà)的監聽(tīng)
HttpSessionListener:監聽(tīng)會(huì )話(huà)的創(chuàng )建以及銷(xiāo)毀事件,如下兩個(gè)方法,
sessionCreated(HttpSessionEvent event),SessionDestoryed(HttpSessionEvent event)
HttpSessionAttributeListener:監聽(tīng)會(huì )話(huà)中添加,替換,刪除屬性事件
HttpSessionBindingListener:監聽(tīng)會(huì )話(huà)與一個(gè)屬性綁定或解除綁定的事件
HttpSessionActivctionListener:監聽(tīng)會(huì )話(huà)被激活或被擱置的事件。
前兩個(gè)必須在web.xml文件中通報各國<listener>元素向容器注冊,后兩個(gè)由會(huì )話(huà)的屬性來(lái)實(shí)現,假如MyData類(lèi),的對象會(huì )作為會(huì )話(huà)的屬性與會(huì )話(huà)綁定,如果希望監聽(tīng)對象與會(huì )話(huà)綁定的解除綁定,以及會(huì )話(huà)被激活或擱置的事件,那么可以讓MyData類(lèi)實(shí)現后兩個(gè)接口。
聯(lián)系客服