Servlet是包package javax.servlet下面的一个接口,一个Java服务端程序,运行在WEB服务器里的Servlet容器里
Servlet处理一个WEB请求的大致流程:
1、用户发送一个HTTP请求
2、Web服务器收到了请求,转发给Servlet容器,此时容器创建两个对象HttpServletRequest和HttpServletResponse
3、根据HTTP请求的URL找到对应Servlet,创建一个单独的线程,传参上面创建的两个对象
4、调用Servlet的service方法,根据不同的method调用HttpServlet类的doGet()和doPost()等方法来响应HTTP请求
5、Web服务器将响应的消息组装成HTTP响应返回给客户端
6、创建的线程技术,以及删除两个对象
由于Servlet运行在容器里,由Servlet容器来控制其生命周期,主要包括初始化,执行和销毁,具体包括:
init():servlet初始化的时候被调用,传了一个ServletConfig接口对象
service():每次有新的请求,都会调用一次service(),都会在独立的线程中运行
destroy():servlet对象需要被销毁时调用,释放被占用的资源
完成Servlet生命周期可以分为加载,创建,初始化,处理请求和销毁这几个阶段
1、加载;容器通过类加载器加载Servlet
2、创建:通过调用Servlet构造方法创建一个Servlet实例
3、初始化:通过调用Servlet的init()方法来完成初始化,只会被调用一次
4、处理请求:Servlet创建之后,每当有新的请求,容器新起一个线程来处理请求,调用service()方法完成不同method的响应
5、销毁:容器在销毁Servlet之前,需要调用destroy()方法,让Servlet释放其占用的系统资源,当destroy()方法被调用后,容器就不会给这个Servlet发送任何请求消息了,这里destroy()方法也只被调用一次,如果调用后,容器需要这个Servlet,必须中心创建并初始化一个新的
简单扫了一眼Servlet处理不同Method的请求流程,比较简单
1、Servlet接口的service()方法
* @param req the <code>ServletRequest</code> object that contains
* the client's request
*
* @param res the <code>ServletResponse</code> object that contains
* the servlet's response
*
* @exception ServletException if an exception occurs that interferes
* with the servlet's normal operation
*
* @exception IOException if an input or output exception occurs
*
*/
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException;
2、service()的实现在HttpServlet里的service()
@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException
{
HttpServletRequest request;
HttpServletResponse response;
if (!(req instanceof HttpServletRequest &&
res instanceof HttpServletResponse)) {
throw new ServletException("non-HTTP request or response");
}
request = (HttpServletRequest) req;
response = (HttpServletResponse) res;
service(request, response);
}
3、最终查看service()方法
/**
* 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
*
* @throws IOException if an input or output error occurs
* while the servlet is handling the
* HTTP request
*
* @throws 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) {
// 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);
}
}
获取请求的method,不同的method执行不同的响应方式