Servlet筆記——(2.2.3)繼承HttpServlet

2.2.3.1 原理

HttpServlet類是GenericServlet的子類,它提供了對HTTP請求的特殊支持,所以通常我們都會通過繼承HttpServlet來完成自定義的Servlet。



2.2.3.2 HttpServlet覆蓋了service(ServletRequest, ServletResponse)方法

HttpServlet類提供了service(HttpServletRequest, HttpServletResponse)方法,這個方法是HttpServlet自己的方法,不是從Servlet繼承下來的。在HttpServlet的service(ServletRequest, ServletResponse)方法中,會把ServletReqest和ServletResponse強轉成HttpServletRequest和HttpServletResponse,然後調用service(HttpServletRequest, HttpServletResponse)方法,這說明子類只需重寫service(HttpServletRequest, HttpServletResponse)方法,而不用自己去強轉請求和響應對象了。

實際應用中其子類也不用去覆蓋service(HttpServletRequest, HttpServletResponse)方法,因爲HttpServlet還要做另一步簡化操作,後面會介紹。下面是HttpServlet的部分源碼:

public abstract class HttpServlet extends GenericServlet {

    /* 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);
          }
       } elseif (method.equals(METHOD_HEAD)) {
long lastModified = getLastModified(req);
            maybeSetLastModified(resp, lastModified);
            doHead(req, resp);
        } elseif (method.equals(METHOD_POST)) {
            doPost(req, resp);
        } elseif (method.equals(METHOD_PUT)) {
            doPut(req, resp);        
        } elseif (method.equals(METHOD_DELETE)) {
            doDelete(req, resp);
        } elseif (method.equals(METHOD_OPTIONS)) {
            doOptions(req,resp);
        } elseif (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);
        }
}

@Override
publicvoid service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
        HttpServletRequest  request;
        HttpServletResponse response;

try {
// 強轉
            request = (HttpServletRequest) req;
            response = (HttpServletResponse) res;
        } catch (ClassCastException e) {
thrownew ServletException("non-HTTP request or response");
        }
          // 調用
        service(request, response);
}
……
}

2.2.3.3 doGet()和doPost()

在HttpServlet的service(HttpServletRequest, HttpServletResponse)方法會去判斷當前請求是GET還是POST,如果是GET請求,那麼會去調用本類的doGet()方法;如果是POST請求,會去調用doPost()方法,這說明我們在子類中只需去覆蓋doGet()或doPost()方法即可。



2.2.3.4 什麼情況下發出GET/POST請求

下面四種情況會發出GET請求:

(1) 直接在瀏覽器地址欄輸入URL地址,然後回車訪問地址;

(2) 頁面上有一個<a href=”http://......”>XXX</a>鏈接,點擊這個鏈接訪問;

(3) 頁面上有一個FORM,明確定義method=”GET”;

(4) 通過javascript代碼:window.location.href=”http://......”來刷新當前頁面;

只有下面一種情況會發出POST請求:頁面上有一個FORM表單,明確定義method=”POST”。

2.2.3.5 GET和POST請求的區別

GET請求通過在URL地址後面附加參數的形式來向後臺遞交數據,格式爲:(http://localhost:8080/servlet/TestServlet01?username=zs&password=123)。即URL?參數名1=參數值1&參數名2=參數值2......。(注意:=兩側不要加空格)

POST請求則通過HTTP HEAD來遞交數據(即不會出現在URL地址的後面)。

由於GET請求是將參數附加在URL地址的後面,所以,它的長度可能會受到瀏覽器的限制(在HTTP協議中,沒有參數長度上限的說法,如果參數長度受限,那是由於特定的瀏覽器或服務決定的,一般IE瀏覽器4000byte);

POST請求的數據長度一般不會受限;

在客戶端,GET與POST的主要區別在於是否是通過URL地址來傳參,GET使用起來很方便,但不適合大批數據的傳輸;POST則需要定義一個FORM表單纔可以使用,稍微麻煩些,所以:大批量數據提交使用POST;數據量少使用GET;

服務器端:一般情況下無需關注是GET還是POST方法提交的數據。無論是GET還是POST,對於服務器來說,其接收從客戶端傳遞過來的參數的過程是完全一樣的。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章