一. GenericServlet
GenericServlet本身是一个抽象类,并且实现了Servlet和ServletConfig接口
其在内部定义了一个私有的ServletConfig类型的变量config,并在init(ServletConfig config)为其赋值,然后通过config实现其他方法。
service(ServletRequest servletrequest, ServletResponse servletresponse)为抽象方法。具体代码如下:
public abstract class GenericServlet implements Servlet, ServletConfig, Serializable { private transient ServletConfig config; public GenericServlet() { }
@override public void init(ServletConfig config) throws ServletException { this.config = config; init(); } // 此方法供我们实现的Servlet初始化时使用 public void init() throws ServletException {}
@override public ServletConfig getServletConfig() { return config; }
@override public String getInitParameter(String name) { return getServletConfig().getInitParameter(name); } public abstract void service(ServletRequest servletrequest, ServletResponse servletresponse) throws ServletException, IOException; // 其他方法略 ... }
二. HttpServlet
为了简化开发,Servlet容器提供了HttpServlet的实现,其继承了GenericServlet.
1. Servlet容器为我们封装了HttpServletRequest, HttpServletResponse类型的参数,传入service方法,在service方法内强转后传入对应的doXXX方法
2. 开发时继承HttpServlet,只需要重写doXXX方法即可,处理相应方式的HTTP请求。
public abstract class HttpServlet extends GenericServlet {
// doXXX方法被子类覆盖 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(405, msg); else resp.sendError(400, msg); } //doPost, doPut, doDelete类似实现, doHead, doTrace, doOption略复杂 ...... //通过此方法调用不同HTTP请求方式的处理方法doXXX protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String method = req.getMethod(); if(method.equals("GET")) { long lastModified = getLastModified(req); if(lastModified == -1L) { doGet(req, resp); } else { long ifModifiedSince; try { ifModifiedSince = req.getDateHeader("If-Modified-Since"); } catch(IllegalArgumentException iae) { ifModifiedSince = -1L; } if(ifModifiedSince < (lastModified / 1000L) * 1000L) { maybeSetLastModified(resp, lastModified); doGet(req, resp); } else { resp.setStatus(304); } } } else if(method.equals("HEAD")) { long lastModified = getLastModified(req); maybeSetLastModified(resp, lastModified); doHead(req, resp); } else if(method.equals("POST")) doPost(req, resp); else if(method.equals("PUT")) doPut(req, resp); else if(method.equals("DELETE")) doDelete(req, resp); else if(method.equals("OPTIONS")) doOptions(req, resp); else if(method.equals("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(501, errMsg); } } //此为GenericServlet中方法,最终调用HttpServlet内实现的service方法 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); } }