学了这么久javaweb,今天我们来介绍一下常见的servlet的生命周期。
一、servlet接口中的方法
找到servlet接口,我们发现servlet接口中一共有五个方法
[Java] 纯文本查看 复制代码 public interface Servlet {
//初始化方法,servlet在加载完毕后,首先执行此方法
public void init(ServletConfig config) throws ServletException;
//获得servlet上下文对象
public ServletConfig getServletConfig();
//每次请求都进入该方法执行
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException;
//获得当前servlet相关信息,如作者、版本、授权等信息
public String getServletInfo();
//销毁servlet时执行此方法
public void destroy();
}
查找servlet的实现类、子接口我们可以看到,servlet有许多实现和子接口,这里我们找到GenericServlet这个抽象类
二、GenericServlet
[Java] 纯文本查看 复制代码 public abstract class GenericServlet implements Servlet, ServletConfig,
java.io.Serializable {
private static final long serialVersionUID = 1L;
private transient ServletConfig config;
public GenericServlet() {
// NOOP
}
@Override
public void destroy() {
// NOOP by default
}
@Override
public String getInitParameter(String name) {
return getServletConfig().getInitParameter(name);
}
@Override
public Enumeration<String> getInitParameterNames() {
return getServletConfig().getInitParameterNames();
}
@Override
public ServletConfig getServletConfig() {
return config;
}
@Override
public ServletContext getServletContext() {
return getServletConfig().getServletContext();
}
@Override
public String getServletInfo() {
return "";
}
@Override
public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
}
public void init() throws ServletException {
// NOOP by default
}
public void log(String msg) {
getServletContext().log(getServletName() + ": " + msg);
}
public void log(String message, Throwable t) {
getServletContext().log(getServletName() + ": " + message, t);
}
@Override
public abstract void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException;
@Override
public String getServletName() {
return config.getServletName();
}
}
GenericServlet这个抽象类,同时实现了Servlet, ServletConfig和序列化接口,对我们的servlet进一步扩展。
三、HttpServlet
最后是我们写自己的servlet实现时最常见的类,HttpServlet,这里面我们看到,它对我们的service方法进行了重载
[Java] 纯文本查看 复制代码 @Override
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);
}
service方法,前面说的servlet每次请求都在这个方法中执行,这里我们可以看到,HttpServlet中,
将ServletRequest、ServletResponse 向下转型为HttpServletRequest 、HttpServletResponse ,然后调用了自己重载的方法
[Java] 纯文本查看 复制代码 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;
try {
ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
} catch (IllegalArgumentException iae) {
// Invalid date header - proceed as if none was set
ifModifiedSince = -1;
}
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的service方法之后,根据请求方式的不同,又调用对应的请求方法,其中就有我们插件的post和get方法
至此,servlet生命周期完毕。我们再梳理一下,servlet加载完毕,首先执行servlet 接口中的init方法,然后每次请求调用service方法,在HttpServlet的
service方法中,根据不同的请求类型,再跳转到对应请求处理方法中;servlet销毁时,执行destroy方法。
|