Servlet(一) servlet的三种创建方式 servlet生命周期(重要) servlet执行过程: HttpServlet类:

不会servlet谈不上会javaweb开发,所以很重要

Servlet(一) servlet的三种创建方式
servlet生命周期(重要)
servlet执行过程:
HttpServlet类:

这个servlet不用new,就是一个java类,可以直接使用,用来处理请求响应的。

写一个java类继承serlvet接口。 重写未实现的方法。其实最关键的一个就是service()方法。 

ServletContext

WEB-INF中不可以直接访问src中的文件:通过以下渠道

四个过程

  1. 执行构造函数(实例化,servlet第一次被访问时)
  2. init(初始化,servlet第一次被访问时)
  3. service 服务,每次被访问都会被调用
  4. destroy 销毁

当servlet开启后再刷新界面的时候,就只执行service函数,当项目被卸载(也就是webroot下的项目被删除了)时,会执行destroy方法。

servlet执行过程:

  1. 先写一个类实现servlet接口。
  2. 然后现在web.xml中配置

上面第二步中:创建一个servlet实例

Servlet(一) servlet的三种创建方式
servlet生命周期(重要)
servlet执行过程:
HttpServlet类:

<servlet-class>这个标签其实就是new这个servlet类,底层代码其实就是classforName,因为Tomcat功能可以解析xml,所以可以这么写

下图可以通过copy qualified name来复制Servlet类的全路径

Servlet(一) servlet的三种创建方式
servlet生命周期(重要)
servlet执行过程:
HttpServlet类:

然后servlet-name 改成小写即可

Servlet(一) servlet的三种创建方式
servlet生命周期(重要)
servlet执行过程:
HttpServlet类:

servlet-mapping:

Servlet(一) servlet的三种创建方式
servlet生命周期(重要)
servlet执行过程:
HttpServlet类:

一定记得加一个/ ,否则就是访问localhost:8080/demo1 (显然这种地址是错的),而不是localhost:8080/项目名/demo1,通过这个映射地址找到servlet类。

对于错误信息:

HTTP Status 405 - HTTP method GET is not supported by this URL

type Status report

message HTTP method GET is not supported by this URL

description The specified HTTP method is not allowed for the requested resource.

Apache Tomcat/7.0.75

原因是在覆盖doPost或者doGet的时候忘记去掉super.doGet或则super.doPost了,去掉就好了。

原理解释:

三步走:

  1. 客户端首先通过地址访问demo1下的内容, tomcat会找到对应的项目,即day08。
  2. 然后会通过web.xml找到url-pattern下  为/demo的标签,然后找到兄弟标签servlet-name对应的servletDemo,
  3. 最后找到对应的servlet类,之后就会调用该类下的service()方法。

时序图如下:

Servlet(一) servlet的三种创建方式
servlet生命周期(重要)
servlet执行过程:
HttpServlet类:

上面在第四步,创建servlet实体类,然后调用init方法。


第一种创建方式:

就像上面的例子一样,写一个类实现servlet接口,然后配置web.xml文件。

第二种创建方式:

GenericServlet类 实现service方法

Servlet(一) servlet的三种创建方式
servlet生命周期(重要)
servlet执行过程:
HttpServlet类:

第三种创建方式

实际开发中,就用这种!

使用方法:创建一个类然后继承HttpServlet类

HttpServlet类:

它是继承GenericServlet类。

doGet doPost service(两个service方法),这三个方法更常用

不建议重写service方法,否则,他自带的service中的doPost doGet方法就没有起到作用了。主要是重写doGet doPost方法。使用HttpServlet其实主要就是要重写doget doPost,因为在HttpServlet中的service最后就是调用doget dopost,这是一个模板(模板方法),模板已经给你搭好了,具体在那两个方法里改变

在HttpServlet类中的service方法

 @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(request, response);调用这个方法,这个方法里的doPost,doGet最终被我们自己重写

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);
        }
    }

 三种创建方式的关系可用下图表示:

Servlet(一) servlet的三种创建方式
servlet生命周期(重要)
servlet执行过程:
HttpServlet类:

使用IDE创建一个Servlet ,就可以不用使用类的方式创建,就不需要手动写web.xml文件

 Servlet(一) servlet的三种创建方式
servlet生命周期(重要)
servlet执行过程:
HttpServlet类:

这样就自动在web.xml中生成以下代码:

Servlet(一) servlet的三种创建方式
servlet生命周期(重要)
servlet执行过程:
HttpServlet类:

Servlet(一) servlet的三种创建方式
servlet生命周期(重要)
servlet执行过程:
HttpServlet类:

访问的时候需要多加一个/servlet串就可以,通常url-pattern项目文件小写。所以改成小写了。


 idea中输入sout就是System.out.println快捷键