Servlet源碼級別進行詳解


1.首先我們先看看Servlet的類結構圖,然后再分別介紹其中的接口方法

由上圖可以看到,Servlet和ServletConfig都是頂層接口類,而GenericServlet實現了這兩個頂層類,然后HttpServlet實現了GenericServlet類.所以要實現一個Servlet直接就可以繼承HttpServlet.

2.Servlet接口代碼

public interface Servlet {
    //容器在啟動的被調用,僅調用一次
    void init(ServletConfig var1) throws ServletException;
    //獲取Servlet配置
    ServletConfig getServletConfig();
    //處理具體請求
    void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
    //獲取Servlet的相關信息
    String getServletInfo();
    //Servlet銷毀后釋放資源
    void destroy();
}

其中,init方法接收一個ServletConfig參數,由容器傳入.ServletConfig就是Servlet的配置,在web.xml中定義Servlet時通過init-param標簽配置的參數由ServletConfig保存.

3.ServletConfig接口定義

public interface ServletConfig {
    //用於獲取Servlet名,web.xml中定義的servlet-name
    String getServletName();
    //獲取應用本身(非常重要)
    ServletContext getServletContext();
    //獲取init-param中的配置參數
    String getInitParameter(String var1);
    //獲取配置的所有init-param名字集合
    Enumeration<String> getInitParameterNames();
}

ServletConfig是Servlet級別,而ServletContext是Context(也就是Application)級別.ServletContext通常利用setAttribute方法保存Application的屬性.

4.Servlet第一個實現類GenericServlet

GenericServlet是Servlet的默認實現,是與具體協議無關的,主要做了三件事.

1) 實現了ServletConfig接口,可以調用ServletConfig里面的方法.

public abstract class GenericServlet implements Servlet, ServletConfig, Serializable

2) 提供了無參的init方法

public void init() throws ServletException {}

3)提供了2個log方法,一個記錄日志,一個記錄異常.

public void log(String msg) {
    this.getServletContext().log(this.getServletName() + ": " + msg);
}

public void log(String message, Throwable t) {
    this.getServletContext().log(this.getServletName() + ": " + message, t);
}

5.基於協議的HttpServlet

HttpSerVlet是基於Http協議實現的Servlet基類,我們在寫Servlet的時候直接繼承它就行了.SpringMVC中的DispatchServlet就是繼承了HttpServlet.HttpServlet重新了service方法,而service方法首先將ServletRequest和ServletResponse轉成HttpServletRequest和HttpServletResponse,然后根據Http不同類型的請求,再路由到不同的處理方法進行處理.

public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
    HttpServletRequest request;
    HttpServletResponse response;
    try {//直接對請求類型進行強轉
        request = (HttpServletRequest)req;
        response = (HttpServletResponse)res;
    } catch (ClassCastException var6) {
        throw new ServletException("non-HTTP request or response");
    }
    //調用Http的請求方法處理
    this.service(request, response);
}
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String method = req.getMethod();//獲取請求類型
    long lastModified;
//根據請求類型進行路由
    if(method.equals("GET")) {
        lastModified = this.getLastModified(req);
        if(lastModified == -1L) {
            this.doGet(req, resp);
        } else {
            long ifModifiedSince;
            try {
                ifModifiedSince = req.getDateHeader("If-Modified-Since");
            } catch (IllegalArgumentException var9) {
                ifModifiedSince = -1L;
            }

            if(ifModifiedSince < lastModified / 1000L * 1000L) {
                this.maybeSetLastModified(resp, lastModified);
                this.doGet(req, resp);
            } else {
                resp.setStatus(304);
            }
        }
    } else if(method.equals("HEAD")) {
        lastModified = this.getLastModified(req);
        this.maybeSetLastModified(resp, lastModified);
        this.doHead(req, resp);
    } else if(method.equals("POST")) {
        this.doPost(req, resp);
    } else if(method.equals("PUT")) {
        this.doPut(req, resp);
    } else if(method.equals("DELETE")) {
        this.doDelete(req, resp);
    } else if(method.equals("OPTIONS")) {
        this.doOptions(req, resp);
    } else if(method.equals("TRACE")) {
        this.doTrace(req, resp);
    } else {
        String errMsg = lStrings.getString("http.method_not_implemented");
        Object[] errArgs = new Object[]{method};
        errMsg = MessageFormat.format(errMsg, errArgs);
        resp.sendError(501, errMsg);
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM