重溫模糊知識點之繼承httpServlet為什麼不重寫service方法
阿新 • • 發佈:2019-01-09
當寫一般的servlet的時候,我們編寫一個servlet 去繼承 GenericServlet ,那麼我們就得覆蓋它的一個抽象方法: abstract service(ServletRequest,ServletResponse)這個抽象方法。
存在這個一個繼承關係:
interface Servlet
|---- abstract GenericServlet
|---abstract HttpServlet
我們在說一說Servlet的生命週期:init-----》service----》destory
1.預設情況下,Servlet是在第一次被訪問的時候呼叫它的init()方法進行初始化的,執行Service方法 後,呼叫destory()方法消亡,生命週期完結。
2.可以進行配置,使得Servlet在容器(tomcat)載入的時候,進行初始化,在web.xml中進行下面的配置:
<servlet>
<servlet-name>Servlet名字</servlet-name>
<servlet-class>servlet完整類名</servlet-class>
<load-on-startup>1(如果初始化的servlet多的話,這裡配置先後次序)</load-on-startup>
</servlet>
當寫一般的servlet的時候,我們編寫一個servlet 去繼承 GenericServlet ,那麼我們就得覆蓋它的一個抽象方法: abstract service(ServletRequest,ServletResponse)這個抽象方法,執行業務,但是為什麼在寫有關Http協議的Servlet的時候,我們沒有重寫service方法?
下面是HttpServlet的原碼:
/** * Receives standard HTTP requests from the public * <code>service</code> method and dispatches * them to the <code>do</code><i>XXX</i> methods defined in * this class. This method is an HTTP-specific version of the * {@link javax.servlet.Servlet#service} method. There's no * need to override this method. * * @param req the {@link HttpServletRequest} object that * contains the request the client made of * the servlet * * @param resp the {@link HttpServletResponse} object that * contains the response the servlet returns * to the client * * @exception IOException if an input or output error occurs * while the servlet is handling the * HTTP request * * @exception ServletException if the HTTP request * cannot be handled * * @see javax.servlet.Servlet#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); } }
通過對原碼的閱讀我們發現,其實HttpServlet已經實現了GenericServlet類的service方法,並且對提交方式(get,post......)進行了一些列的判斷,執行相應的do....()方法.我們看一下HttpServlet中doget dopost方法的實現:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String protocol = req.getProtocol(); String msg = lStrings.getString("http.method_get_not_supported"); if (protocol.endsWith("1.1")) { resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg); } else { resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg); } } protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String protocol = req.getProtocol(); String msg = lStrings.getString("http.method_post_not_supported"); if (protocol.endsWith("1.1")) { resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg); } else { resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg); } }
通過閱讀dopost和doget的原碼,我們可以看到,doget和dopost都有預設的實現,但是這個實現是“通知實現類去重寫 該方法的提示資訊”----也就是說,我們必須在HttpServlet的實現類裡實現doget和dopost方法,並且,不能去重寫service(httpServletRequest,HttpServletResponse)這個方法(實現後,就不能執行do....()方法了),所以不建議並且不能實現service方法。