一、Servlet生命周期:

Servlet加载、实例化、初始化、服务、销毁。

1、初始化init():

当服务启动时,Servlet被装入tomcat或者其他服务器容器时执行(服务器容器从启动到停止期间唯一的一次)init()初始化方法,负责初始化Servlet对象,无论有多少个请求访问Servlet,初始化init()只会启动一次,不会重复执行。

2、服务service:

服务service方法是Servlet核心,该方法有两个参数HttpServletRequest arg0, HttpServletResponse arg1:

Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象、和代表响应的response对象。
request和response对象即然代表请求和响应,那我们要获取客户机提交过来的数据,只需要找request对象就行了。要向客户机输出数据,只需要找response对象就行了。

HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象提供的方法,可以获得客户端请求的所有信息。

HttpServletResponse对象代表服务器的响应。这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。查看HttpServletResponse的API,可以看到这些相关的方法。

在HttpServlet中已存在Service()方法。默认的服务功能是调用与HTTP请求的方法相应的do功能(这种doXxx的方法也叫钩子方法如doGet,doPost)。

如果在继承HttpServlet的类中对Serlvet进行重写,那么客户端请求Serlvet的时候,就会

去子类中调用重写的service方法(一般不对Serlvet方法进行重写)

3、销毁destroy():

Serlvet在tomcat等服务器停止运行且卸载它时调用销毁destroy()方法,因为service方法运行时有可能有多个线程,当执行了销毁destroy()方法,这些线程就全部终止。

二、ServletTomcat等服务器关系:

  1. web客户端 向Servlet容器(Tomcat)发出Http请求
  2. Servlet容器接收web客户端的请求
  3. Servlet容器创建一个HttpRequest对象,将Web
    Client请求的信息封装到这个对象中。
  4. Servlet容器创建一个HttpResponse对象
  5. Servlet容器调用HttpServlet对象的service方法,把HttpRequest对象与HttpResponse对象作为参数传给 HttpServlet 对象。
  6. HttpServlet调用HttpRequest对象的有关方法,获取Http请求信息。
  7. HttpServlet调用HttpResponse对象的有关方法,生成响应数据。
  8. Servlet容器把HttpServlet的响应结果传给Web
    Client。

三、Servlet工作原理:

1、当web客户端发送一个Http请求,Servlet创建HttpRequest对象和HttpResponse对象,将web客户端请求的信息封装到HttpRequest对象中,Servlet将HttpRequest对象和HttpResponse对象作为参数传递给HttpServlet中的service()方法,通过HttpRequest中封装的Http请求信息获取请求方式对请求进行响应的,选择调用doGet,doPost等这些钩子方法,然后再进入对应的方法中调用逻辑层的方法,实现对客户的响应。在Servlet接口和GenericServlet中是没有doGet()、doPost()等等这些钩子方法的,HttpServlet中定义了这些方法,但是都是返回error信息,所以,我们每次定义一个Servlet的时候,都必须实现doGet或doPost等这些方法。

如果服务器启动时就创建Servlet,那么还需要在web.xml文件中配置<load-on-startup>1</load-on-startup>。Servlet是在第一次被访问时由服务器创建的,而且一个Servlet类型,服务器只创建一个实例对象,它是单例的。

2、每一个自定义的Servlet都必须实现Servlet的接口,Servlet接口中定义了五个方法,其中比较重要的三个方法涉及到Servlet的生命周期,分别是上文提到的init(),service(),destroy()方法。GenericServlet是一个通用的,不特定于任何协议的Servlet,它实现了Servlet接口。而HttpServlet继承于GenericServlet,因此HttpServlet也实现了Servlet接口。所以我们定义Servlet的时候只需要继承HttpServlet即可。

服务器接收到一次请求,就会调用service() 方法一次。

3、Servlet接口和GenericServlet是不特定于任何协议的,而HttpServlet是特定于HTTP协议的类,所以HttpServlet中实现了service()方法,并将请求ServletRequest、ServletResponse 强转为HttpRequest 和 HttpResponse。

四、创建Servlet对象

1、Servlet容器启动时:读取web.xml配置文件中的信息,构造指定的Servlet对象,创建ServletConfig对象,同时将ServletConfig对象作为参数来调用Servlet对象的init方法。

2、在Servlet容器启动后:客户首次向Servlet发出请求,Servlet容器会判断内存中是否存在指定的Servlet对象,如果没有则创建它,然后根据客户的请求创建HttpRequest、HttpResponse对象,从而调用Servlet 对象的service方法。

3、Servlet Servlet容器在启动时自动创建Servlet,这是由在web.xml文件中为Servlet设置的<load-on-startup>属性决定的。从中我们也能看到同一个类型的Servlet对象在Servlet容器中以单例的形式存在。

三、Servlet概述
Servlet是JavaWeb的三大组件之一,它属于动态资源。都会在web.xml中配置,例如如上图
Servlet的作用是处理请求,服务器会把接收到的请求交给Servlet来处理,在Servlet中通常需要:
    Tomcat服务器会帮助我们将请求的数据封装在request对象
    Tomcat同样会创建respose对象给我们使用,让我们响应 HttpServletRequest extends ServletRequest
  例如客户端发出登录请求,或者输出注册请求,这些请求都应该由Servlet来完成处理!
    我们需要实现自己的逻辑业务就需要自己来编写Servlet,每个Servlet必须实现javax.servlet.Servlet接口。

实现Servlet有三种方式:
1.实现javax.servlet.Servlet接口;
2.继承javax.servlet.GenericServlet类;
3.继承javax.servlet.http.HttpServlet类;

  开发中通常我们会去继承HttpServlet类来完成我们的Servlet,生命周期方法由Tomcat来调用,我们只是完成接受请求,然后响应,完成业务逻辑代码
    Tomcat服务器帮助我们完成不变的代码,我们来完成业务需求变化的代码
    我们的代码和Tomcat代码合起来构成一个完成的代码

四、补充:

近期发现对:

1、为什么不建议重写service方法?

2、servlet中为什么一定要重写doGet以及doPost方法?

3、servlet的父类;

有了新的认识,进行补充;

1、为什么不建议重写service方法?

因为客户端每一次发送请求,服务端都会调用一次servlet中service方法,而service方法其实是类似调度的功能,

service方法源码:

protected void service(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException
    {
        String method = req.getMethod();
        if(method.equals("GET"))
        {
            long lastModified = getLastModified(req);
            if(lastModified == -1L)
            {
                doGet(req, resp);
            } else
            {
                long ifModifiedSince = req.getDateHeader("If-Modified-Since");
                if(ifModifiedSince < (lastModified / 1000L) * 1000L)
                {
                    maybeSetLastModified(resp, lastModified);
                    doGet(req, resp);
                } else
                {
                    resp.setStatus(304);
                }
            }
        } else
        if(method.equals("HEAD"))
        {
            long lastModified = getLastModified(req);
            maybeSetLastModified(resp, lastModified);
            doHead(req, resp);
        } else
        if(method.equals("POST"))
            doPost(req, resp);
        else
        if(method.equals("PUT"))
            doPut(req, resp);
        else
        if(method.equals("DELETE"))
            doDelete(req, resp);
        else
        if(method.equals("OPTIONS"))
            doOptions(req, resp);
        else
        if(method.equals("TRACE"))
        {
            doTrace(req, resp);
        } else
        {
            String errMsg = lStrings.getString("http.method_not_implemented");
            Object errArgs[] = new Object[1];
            errArgs[0] = method;
            errMsg = MessageFormat.format(errMsg, errArgs);
            resp.sendError(501, errMsg);
        }
    }

可以看出来,如果我们重写了service方法,没有实现对doGet和doPost等doxxx方法的调用,那么请求就得不到处理。

如果不对service方法重写,那么会执行HttpServlet方法中service方法。

2、servlet中为什么一定要重写doGet以及doPost方法?

因为在service方法对请求的方式进行了匹配,如Get方法就调用doGet方法,所以一定要根据业务逻辑对doGet或者doPost等doxxx方法进行重写

3、servlet的父类

GenericServlet是Servlet接口的实现类,我们可以通过继承GenericServlet来编写自己的Servlet。

GenericServlet还实现了ServletConfig接口,所以可以直接调用getInitParameter()、getServletContext()等ServletConfig的方法。

具体源码可以反编译去查看:

GenericServlet的init()方法
在GenericServlet中,定义了一个ServletConfig config实例变量,并在init(ServletConfig)方法中把参数ServletConfig赋给了实例变量。然后在该类的很多方法中使用了实例变量config。
如果子类覆盖了GenericServlet的init(StringConfig)方法,那么this.config=config这一条语句就会被覆盖了,也就是说GenericServlet的实例变量config的值为null,那么所有依赖config的方法都不能使用了。如果真的希望完成一些初始化操作,那么去覆盖GenericServlet提供的init()方法,它是没有参数的init()方法,它会在init(ServletConfig)方法中被调用。

HttpServlet类是GenericServlet的子类,它提供了对HTTP请求的特殊支持,所以通常我们都会通过继承HttpServlet来完成自定义的Servlet。

HttpServlet覆盖了service()方法
HttpServlet类中提供了service(HttpServletRequest,HttpServletResponse)方法,这个方法是HttpServlet自己的方法,不是从Servlet继承来的。在HttpServlet的service(ServletRequest,ServletResponse)方法中会把ServletRequest和ServletResponse强转成HttpServletRequest和HttpServletResponse,然后调用service(HttpServletRequest,HttpServletResponse)方法,这说明子类可以去覆盖service(HttpServletRequest,HttpServletResponse)方法即可,这就不用自己去强转请求和响应对象了。

就是直接继承HttpServlet,然后无需进行重写,就可以实现ServletRequest和ServletResponse强转成HttpServletRequest和HttpServletResponse,因为在HttpServlet类已经实现了这一操作

借鉴于https://blog.csdn.net/tanyunlong_nice/article/details/42536461

Servlet运行原理以及生命周期的更多相关文章

  1. HTTP协议 Servlet入门 Servlet工作原理和生命周期 Servlet细节 ServletConfig对象

    1 HTTP协议特点   1)客户端->服务端(请求request)有三部份     a)请求行--请求行用于描述客户端的请求方式.请求的资源名称,以及使用的HTTP协议版本号 请求行中的GET ...

  2. jsf的运行原理及生命周期

    一.jsf(java server faces)的运行原理(工作方式) 1.jsf应用是事件驱动的,当一个事件发生时(比如用户单击一个按钮),事件通知通过HTTP发往服务器,服务器端使用叫做Faces ...

  3. SpringMVC内容略多 有用 熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器、过滤器等Web组件以及MVC架构模式进行Java Web项目开发的经验。

    熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器.过滤器等Web组件以及MVC架构 ...

  4. Servlet 运行原理

    一:servlet定义 Servlet是一个Java应用程序,运行在服务器端,用来处理客户端请求并作出响应的程序. 二:简单servlet实例 //导入所需的包 import javax.servle ...

  5. JavaWeb之 Servlet执行过程 与 生命周期

    Servlet的概念 什么是Servlet呢? Java中有一个叫Servlet的接口,如果一个普通的类实现了这个接口,这个类就是一个Servlet.Servlet下有一个实现类叫HttpServle ...

  6. [转]JavaWeb之 Servlet执行过程 与 生命周期

    https://www.cnblogs.com/vmax-tam/p/4122105.html Servlet的概念 什么是Servlet呢? Java中有一个叫Servlet的接口,如果一个普通的类 ...

  7. PHP的工作原理和生命周期

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u013778883/article/details/79831035   php是一门适用于web开 ...

  8. JavaEE Servlet 核心方法及生命周期

    做JavaWeb开发,免不了要和Servlet打交道.Servlet是Sun(Oracle)官方定义的一个Web开发规范,所有Servlet开发都必须遵守.自己以前也没有从头做过Web开发,所以这方面 ...

  9. 【servlet】Servlet的API和生命周期]

    创建时间:6.15 一.Servlet的API(生命周期) (1)Servlet接口中的方法 1)init(ServletConfig config) 何时执行:servlet对象创建的时候执行 Se ...

随机推荐

  1. 解决Office 2016客户端如何同SharePoint Server2016安装在一起

    前言 Microsoft Office 2016 客户端默认使用新式验证. 在某些配置中,新式验证不受安装有 SharePoint Server 2016 的 Office 2016 客户端的支持,例 ...

  2. springmvc中为我们做了什么

    这应该是每个使用框架的人应该自问的.这就要从没有使用框架时说.在没用框架开发web应用时,自己是怎么开发的,就是写servlet,jsp. 使用springmvc后,使用Controller注解,其实 ...

  3. 下载Crypto,CyCrypto,PyCryptodome 报错问题

    python下载Crypto,CyCrypto,PyCryptodome,如有site-packages中存在crypto.pycrypto,在pip之前,需要pip3 uninstall crypt ...

  4. 谷歌浏览器(Chrome)禁止浏览器缓存 设置

    在开发项目期间用谷歌浏览器调试,他总是缓存我的css样式这个很气人啊,后经过摸索找到了方法,如下 先F12或者shift+ctrl+j 打开调试者工具,在找Network这个tab按钮,点击进入,勾选 ...

  5. 推举算法 AdaBoost 哥德尔奖 Godel Prize

    推举算法 AdaBoost  2003年理论计算机科学界最高奖 哥德尔奖 Godel Prize

  6. Web开发——HTML基础

    文档资料参考: 参考:MDN官网 参考:http://www.runoob.com,W3School 参考:https://developer.mozilla.org/zh-CN/docs/Learn ...

  7. 目标检测(七)YOLOv3: An Incremental Improvement

    项目地址 Abstract 该技术报告主要介绍了作者对 YOLOv1 的一系列改进措施(注意:不是对YOLOv2,但是借鉴了YOLOv2中的部分改进措施).虽然改进后的网络较YOLOv1大一些,但是检 ...

  8. 【数据可视化-Echarts】Echart基础

    林峰老师Echart基础课程笔记

  9. 格式化输出&初始编码&运算符

    一:格式化输出 %     %d   %s %为占位符   S替换的内容的类型为字符型 d替换的内容为整型 若在格式化输出的时候需要正常用到% 则表示时用两个%%表示 如: name = input( ...

  10. 【UML】NO.54.EBook.6.UML.2.002-【Thinking In UML 大象 第二版】- UML 核心元素

    1.0.0 Summary Tittle:[UML]NO.54.EBook.6.UML.2.002-[Thinking In UML 大象 第二版]- UML 核心元素 Style:DesignPat ...