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); } }