从官网下载Tomcat源码:Source Code Distributions,关联到Eclipse中。
1、查看HttpServlet中的service(ServletRequest req, ServletResponse res)方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public void service (ServletRequest req, ServletResponse res) throws ServletException, IOException { HttpServletRequest request; HttpServletResponse response; try { request = (HttpServletRequest) req; response = (HttpServletResponse) res; } catch (ClassCastException e) { throw new ServletException ("non-HTTP request or response" ); } service(request, response); }
可以发现,这里把相应的request和response转换为了基于HTTP协议的相应对象。
Servlet接口中定义了一个service方法,HttpServlet对该方法进行了实现,将ServletRequest和ServletResponse转换为HttpServletRequest和HttpServletResponse。
2、继续查看HttpServlet中的service(HttpServletRequest req, HttpServletResponse resp)方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 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 ) { doGet(req, resp); } else { long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE); if (ifModifiedSince < (lastModified / 1000 * 1000 )) { 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 { 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); } }
可以发现,客户端的请求先提交给Service方法时,先获取提交的方法名,根据方法名调用相应的具体方法。
如果重写了该方法,那么就不会根据方法名调用其他具体的方法了。
3、接下来找个相关的具体方法doGet看看:
1 2 3 4 5 6 7 8 9 10 11 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); } }
发现该方法只是判断协议类型,然后抛出相应的异常,其他什么都没做。
所以,在实现自己的Servlet时,需要重写这些方法,以符合自己的需求。一般不需要重写service方法。