A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

学了这么久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方法。

Snipaste_2020-01-09_13-26-47.png (60.01 KB, 下载次数: 18)

Snipaste_2020-01-09_13-26-47.png

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马