Servlet编程需要使用到javax.servlet.servlet和javax.servlet.http包下的接口和类。
其中javax.servlet.servlet接口是最重要的。所有的servlet程序都必须实现该接口和继承自该接口中的类。
Servlet接口
public interface Servlet {
public void init(ServletConfig config) throws ServletException;
public ServletConfig getServletConfig();
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException;
public String getServletInfo();
public void destroy();
}
在接口中声明了5个方法,
init()
, service()
, destroy()
方法与servlet生命周期相关。
servlet生命周期
- 当实例化某个servlet类后,servlet容器会调用
init()
方法进行初始化。servlet容器只会调用该方法一次。程序员可以覆盖此方法,在其中执行一次需要初始化的代码,比如数据库驱动,初始化默认参数。 - 当服务请求到来,servlet容器会调用
service()
方法,将javax.servlet.ServletRequest 对象和 javax.servlet.ServletResponse对象作为参数传入,ServletRequest对象包含了客户端的HTTP请求信息,ServletResponse对象则封装了servlet响应信息。在生命周期中service()
方法会被多次调用。 - 在将实例从服务中移除前, servlet容器会调用servlet实例的
destory()
方法。一般当servlet容器关闭或者是servlet容器要释放内存时,才会将servlet实例移除,而且当servlet实例的service()
方法中所有线程退出或超时,才会调用destroy()
方法。调用destroy()
方法让servlet去释放自己所占有的资源。
Servlet
┗ GenericServlet
┗HttpServlet
Servlet的抽象实现类javax.servlet.GenericServlet则实现了获得名字、配置、初始化参数的方法。该类实现javax.servlet.ServletConfig接口,提供Servlet各种配置和初始信息。
public interface ServletConfig {
public String getServletName();
public ServletContext getServletContext();
public String getInitParameter(String name);
public Enumeration<String> getInitParameterNames();
}
javax.servlet.HttpServlet继承自GenericServlet,扩展了service()
方法,用户发送的HTTP请求类型(POST
,GET
,…)都是在该方法中处理,然后将请求依据请求类型派发至各种请求处理方法doGet()
, doPost()
, doHead()
。该类也是一个抽象类, 所以当我们使用时主要是继承该类,然后重写具体的处理方法doGet()
,doPost()
。 一般情况下,我们并不会去动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);
}
}
可以看到 HttpServlet 对 service()
的实现 只是简单的请求转发至方法。