(一)servlet類
Servlet主要類、接口的結構如下圖所示:
要編寫一個Servlet需要實現javax.servlet.Servlet接口,該接口定義了5個方法。如下:
1.init(),初始化servlet對象,完成一些初始化工作。
它是由servlet容器控制的,該方法只能被調用一次,初始化過程如下:
2.service(),接受客戶端請求對象,執行業務操作,利用響應對象響應客戶端請求。
3.destroy(),當容器監測到一個servlet從服務中被移除時,容器調用該方法,釋放資源。
4.getServletConfig(),ServletConfig是容器向servlet傳遞參數的載體。
5.getServletInfo(),獲取servlet相關信息。
(二)與servlet相關的接口
從servlet僅有的5個方法當中,我們知道其涉及3個接口,分別是:
ServletConfig
ServletRequest
ServletResponse
2.1. ServletConfig
主要方法:
重點關注getServletContext,之前說servletConfig是容器向servlet傳遞參數的載體,那麼它也可以讓Servlet獲取其在容器中的上下文。
ServletContext是針對一個web應用,jdk中具體描述——
There is one context per "web application" per Java Virtual Machine. (A "web application" is a collection of servlets and content installed under a specific subset of the server's URL namespace such as /catalog
and possibly installed via a .war
file.)
2.2.ServletRequest
獲取客戶端發來的請求數據。(查看api)
note:注意getAttribute和getParameter的區別。
getAttribute( String name )可以得到由setAttribute()設置的參數值,相當於是使用getAttribute()得到一
個自己定義的參數,而不是從客戶端得到的參數。
getParameter( String name )它用來獲取客戶端通過get或post方法等傳遞過來的值,是從客戶端傳遞過來的,
一般指的是客戶端提交的表單組件的值。
note:setCharacterEncoding在什麼時候使用纔有效?
它可以覆蓋請求正文中所使用的字符編碼,但是它必須在讀取parameters之前設置,否則無效。
2.3.ServletResponse
響應客戶端請求。(查看api)
(三)GenericServlet抽象類
爲了簡化serlvet的編寫,在javax.servlet包中提供了一個抽象類GenericServlet,它給出了除service()方法以外的簡單實現。
GenericServlet定義了一個通用的,不依賴具體協議的Servlet,它實現了Servlet接口和ServletConfig接口。
public abstract class GenericServlet implements Servlet, ServletConfig, java.io.Serializable
(四)HttpServlet抽象類
HttpServlet主要是應用於HTTP協議的請求和響應,爲了快速開發HTTP協議的serlvet,sun提供了一個繼承自GenericServlet的抽象類HttpServlet,
用於創建適合Web站點的HTTP Servlet。
public abstract class HttpServlet extends GenericServlet implements java.io.Serializable
重點關注HttpServlet中的一個私有方法service。
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); } } }
else if (method.equals(METHOD_HEAD))
{ 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); } } |
而它實現Servlet接口的service方法,是將ServletResponse對象和ServletRequest對象轉化成httpServletResponse對象和HttpservletRequest對象,
然後再調用私有方法service。它根據request獲取Http method(get、post等)的名稱,根據http method調用不同的方法執行操作。
(五)HttpServletRequest、HttpServletResponse
由於HttpServletRequest和HttpServletResponse都是基於Http協議“升級改造”的,所以這兩個對象較之ServletRequest和ServletResponse多出的方法主要和
Http協議相關。
例如:Cookie、request(response)headers、Session、URL等。
具體請查看api。
(六)重點
6.1.servlet的生命週期。
6.2.servlet的上下文。