Servlet也是JavaEE的一种规范,位于javax.servlet下,Servlet规范还包含Filter。该包下分为两部分:servlet有关和http有关。
为什么会有两部分?设计该规范时认为Servlet是一种服务模型,不应与协议耦合,因此就抽象出了一个 javax.servlet,同时提供一套基于HTTP协议上的Servlet扩展,当然就现在看,还没有基于其他协议的流行的Servlet实现。也是因为HttpServlet的普遍性,本文以此为例说明。
从宏观上来看,HttpServlet基于“请求-响应”模型:用户发出请求,服务端响应用户。说到这点,可以先来看看CGI。Common Gateway Interface,通用网关接口,执行过程为:
Servlet的出现弥补了以上缺点,我们知道HttpServlet:
下面来看一下HttpServlet的执行流程:
解释一下:
而各种V层框架仅仅是对这两个类的进一步封装,再怎么操作,最终还是操作的HttpServletRequest和HttpServletResponse。
public interface Servlet { public abstract void init(ServletConfig servletconfig) throws ServletException; public abstract ServletConfig getServletConfig(); public abstract void service(ServletRequest servletrequest, ServletResponse servletresponse) throws ServletException, IOException; public abstract String getServletInfo(); public abstract void destroy(); }Servlet定义了生命周期有关的和读取配置的接口,它的作用就是规定声明周期管理、接受ServletRequest和ServletResponse。
package javax.servlet; import java.io.IOException; import java.io.Serializable; import java.util.Enumeration; import java.util.ResourceBundle; // Referenced classes of package javax.servlet: // Servlet, ServletConfig, ServletException, ServletContext, // ServletRequest, ServletResponse public abstract class GenericServlet implements Servlet, ServletConfig, Serializable { public void destroy() { } public void init(ServletConfig config) throws ServletException { this.config = config; init(); } public void init() throws ServletException { } //省略其他函数 }
package javax.servlet.http; import java.io.IOException; import java.io.Serializable; import java.lang.reflect.Method; import java.text.MessageFormat; import java.util.Enumeration; import java.util.ResourceBundle; import javax.servlet.*; // Referenced classes of package javax.servlet.http: // NoBodyResponse, HttpServletRequest, HttpServletResponse public abstract class HttpServlet extends GenericServlet implements Serializable { public HttpServlet() { } //省略部分函数 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); } 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 = req.getDateHeader("If-Modified-Since"); 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); } } 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); } 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(405, msg); else resp.sendError(400, msg); } //省略doHead、doDelete等方法 }