• 【Servlet】3:Servlet 的基本原理、Servlet对象的生命周期


    目录

    第五章 | 动态资源与Servlet

    | 章节概述

    | Tomcat与Servlet的 原理、关系

    Tomcat的基本构成​编辑

    Server处理HTTP请求

    Connector内部架构分析

    Container内部架构分析

    Tomcat的执行流程小结

    | Servlet 概述、接口实现

    Servlet的基本概述

    实现Servlet接口并通过URL访问:四大步骤

    IDEA一键生成Servlet实现类

    | Servlet对象的 周期与load-on-startup


    本文章属于后端全套笔记的第三部分

    (更新中)【后端入门到入土!】Java+Servlet+JDBC+SSM+SpringBoot+SpringCloud 基础入门_m0_57265007的博客-CSDN博客一篇文章,后端入门到入土。包含 Java基础+高级、MySQL、JDBC、Servlet、SSM、SpringBoot、SpringCloud、项目 的笔记。https://blog.csdn.net/m0_57265007/article/details/127962617?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22127962617%22%2C%22source%22%3A%22m0_57265007%22%7D

    第五章 | 动态资源与Servlet

    | 章节概述

    本章将学习

    • 通过Tomcat的基本原理,引出Servlet的基本原理(理论基础)

    • 掌握Servlet在IDEA中创建其实现类、注册配置实现类到Tomcat、部署、访问的一系列步骤。同时学会使用IDEA快速生成Servlet类的敲门

    • Servlet对象的生命周期、被创建的时机、load-on-time参数

    • HttpServletRequest 解析HTTP请求并发送给服务器

    • HttpServletResponse 响应HTTP请求

    • 多Servlet间数据共享

    • 多Servlet间调用规则


    | Tomcat与Servlet的 原理、关系

    Tomcat的基本构成

    1、Tomcat中最顶层的容器是Server,代表着整个服务器,一个Server可以包含至少一个Service,用于具体提供服务。

    2、Service主要包含两个部分:Connector和Container。 Tomcat 的心脏就是这两个组件,这两个组件的作用:Connector用于处理连接相关的事情,并提供Socket与Request和Response相关的转化;Container用于封装和管理Servlet,以及具体处理Request请求。

    3、一个Tomcat中只有一个Server,一个Server可以包含多个Service,一个Service只有一个Container,但是可以有多个Connectors,因为一个服务可以有多个连接,如同时提供Http和Https链接,也可以提供向相同协议不同端口的连接。

    4、多个 Connector 和一个 Container 就形成了一个 Service,有了 Service 就可以对外提供服务了,但是 Service 还要一个生存的环境,必须要有人能够给她生命、掌握其生死大权,那就非 Server 莫属了!所以整个 Tomcat 的生命周期由 Server 控制。另外,上述的包含关系或者说是父子关系,都可以在tomcat的conf目录下的server.xml配置文件中看出。

    5、Server标签设置的端口号为8005(注意:Server标签的端口号8005用于监听Tomcat的Server接口;而Tomcat端口8080是用于监视来自外部的HTTP请求。两者是不一样的概念!),shutdown=”SHUTDOWN” ,表示在8005端口监听“SHUTDOWN”命令,如果接收到了就会关闭Tomcat。一个Server有一个Service,当然还可以进行配置,一个Service有多个,Service左边的内容都属于Container的,Service下边是Connector。


    Server处理HTTP请求

    1.用户在浏览器中输入该网址,请求被发送到本机端口8080,被在那里监听的Coyote HTTP/1.1 Connector获得;

    2.Connector把该请求交给它所在的Service的Engine(Container)来处理,并等待Engine的回应;

    3.Engine获得请求localhost/test/index.jsp,匹配所有的虚拟主机Host;

    4.Engine匹配到名为localhost的Host(即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机),名为localhost的Host获得请求/test/index.jsp,匹配它所拥有的所有Context。Host匹配到路径为/test的Context(如果匹配不到就把该请求交给路径名为“ ”的Context去处理);

    5.path=“/test”的Context获得请求/index.jsp,在它的mapping table中寻找出对应的Servlet。Context匹配到URL Pattern为*.jsp的Servlet,对应于JspServlet类;

    6.构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet()或doPost(),执行业务逻辑、数据存储等;

    7.Context把执行完之后的HttpServletResponse对象返回给Host;

    8.Host把HttpServletResponse对象返回给Engine;

    9.Engine把HttpServletResponse对象返回Connector;

    10.Connector把HttpServletResponse对象返回给客户Browser。


    Connector内部架构分析

    • Connector用于接受请求并将请求封装成Request和Response,然后交给Container进行处理,Container处理完之后在交给Connector返回给客户端

    • Connector就是使用ProtocolHandler来处理请求的,不同的ProtocolHandler代表不同的连接类型


    Container内部架构分析

    (1)Engine:引擎,用来管理多个站点,一个Service最多只能有一个Engine;

    (2)Host:代表一个站点,也可以叫虚拟主机,通过配置Host就可以添加站点;

    (3)Context:代表一个应用程序,对应着平时开发的一套程序,或者一个WEB-INF目录以及下面的web.xml文件;

    (4)Wrapper:每一Wrapper封装着一个Servlet;

    Context和Host的区别是Context表示一个应用,我们的Tomcat中默认的配置下webapps下的每一个文件夹目录都是一个Context,其中ROOT目录中存放着主应用,其他目录存放着子应用,而整个webapps就是一个Host站点。


    Tomcat的执行流程小结

    1. 首先,使用 startup 命令,Server标签的端口号8005监听到命令后,开启Tomcat服务器的服务

    2. 客户端发起请求,Tomcat的8080端口收到请求,开始一系列的处理

    3. 当一个请求发送到Tomcat之后,首先经过Service然后会交给Connector,Connector用于接收请求并将接收的请求封装为Request和Response来具体处理,Request和Response封装完之后再交由Container内的Servlet进行处理,Container处理完请求之后再返回给Connector,最后在由Connector通过Socket将处理的结果返回给客户端,这样整个请求的就处理完了!

    4. Connector最底层使用的是Socket来进行连接的,Request和Response是按照HTTP协议来封装的,所以Connector同时需要实现TCP/IP协议和HTTP协议!

    • 最后总结一下:

      (1)Tomcat中只有一个Server,一个Server可以有多个Service(用于具体提供服务),一个Service可以有多个Connector(因为一个服务可以有多个连 接)和一个Container; (2) Server掌管着整个Tomcat的生死大权; (4)Service 是对外提供服务的; (5)Connector用于接受请求并将请求封装成Request和Response来具体处理; (6)Container用于封装和管理Servlet,以及具体处理request请求;


    | Servlet 概述、接口实现

    Servlet的基本概述

    • 前面提到了,Servlet 是存在于 Tomcat中的Container中的Wrapper中的一个接口。对于程序员而言,无需深入Tomcat的底层实现。我们只需要知道:Javaweb开发,很大程度上就是在操作Tomcat中的Servlet接口:编写Servlet实现类的代码、在Tomcat的网站核心配置文件 web.xml中配置Servlet实现类对象和URL的映射关系等等……

    • 狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。Servlet运行于支持Java的应用服务器中。从原理上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。

    • Servlet的作用:

      • 在Servlet规范中,指定【动态资源文件】开发步骤

      • 在Servlet规范中,指定Http服务器调用动态资源文件规则

      • 在Servlet规范中,指定Http服务器管理动态资源文件实例对象规则

    • Tomcat服务器目录下lib文件有一个servlet-api.jar。这个就是Servlet接口的jar包~

    • Servlet规范中,HTTP服务器(Tomcat)能调用的【动态资源文件】必须是一个Servlet接口实现类


    实现Servlet接口并通过URL访问:四大步骤

    【前期准备】创建一个web Module

    Step1.创建一个普通Java Module

    Step2.右键模块,添加WEB框架支持。点击确认,就创建好了一个网站

    【Step1】编写一个类,实现HttpServlet接口

    • 一般是继承Servlet接口已经写好的实现类HttpServlet,而不是直接 implements Servlet接口。目的是简化需要重写的方法数量,减少开发难度

    • 若没有导入Servlet类的Jar包,可以Ctrl+Alt+Shift+S  打开 Project Structure - Module - 对应Module。添加 Tomcat目录/lib 下的Servlet.jar

    1. //src/controller/MyServlet.java
    2. public class MyServlet extends HttpServlet {
    3. }

    【Step2】根据需要,重写HttpServlet的 doGet( ) 或 doPost( ) 方法

    • IDEA中快捷键:Ctrl+O 选择 doGet 和 doPost

    • 通过浏览器URL发送的请求都是GET请求,这里只重写GET即可(POST请求一般由前端method控制,或者重定向控制

    【目录结构同Step1】

    1. //src/controller/MyServlet.java
    2. public class MyServlet extends HttpServlet {
    3. @Override
    4. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    5. //super.doGet(req, resp); 如果你是要彻底覆盖父类的doGet方法,不需要父类提供的功能,就可以删除super.doGet(req,resp);这一句
    6. System.out.println("这是Servlet的doGet方法");
    7. }
    8. @Override
    9. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    10. //super.doPost(req, resp);
    11. }
    12. }

    【Step3】在web.xml配置文件中,把开发好的java类注册到web服务器(Tomcat)

    • web.xml的作用主要是:指定对应Servlet实现类的路径、对象名、以及对象名对应URL的名字

    • Servlet实现类的路径、对象名 写在 里面

      Servlet实现类的对象名和URL的映射 写在 里面

      易错:<url-pattern>/web1</url-pattern> 中的别名,一定要以 / 开头!!!!

    1. "1.0" encoding="UTF-8"?>
    2. <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
    5. version="4.0">
    6. <servlet>
    7. <servlet-name>MyServletNameservlet-name>
    8. <servlet-class>controller.MyServletservlet-class>
    9. servlet>
    10. <servlet-mapping>
    11. <servlet-name>MyServletNameservlet-name>
    12. <url-pattern>/web1url-pattern>
    13. servlet-mapping>
    14. web-app>

    【Step4】把网站部署到web服务器(Tomcat):运行 – 编辑配置 – 部署

    部署步骤同 IDEATomcat 静态资源网站访问

    然后部署后,进入浏览器访问即可


    IDEA一键生成Servlet实现类

    • 在一键生成前,需要确保当前Mudule(Ctrl+Alt+Shift+S 打开Project Structure)导入了Servlet包

    右键,选择Servlet即可(注意Servlet的实现类所属包一般都是controller下)

    • 若没有发现有Servlet选项,则还是建议你老老实实自己创建吧……反正也不麻烦。

    • 选项里没有Servlet的解决办法(不推荐使用,会破坏目录结构,仅作参考)参考资料

     

    | Servlet对象的 周期与load-on-startup

    Servlet对象的生命周期

    1. 网站中所有的Servlet接口实现类的实例对象,只能由Http服务器负责创建。开发人员不能手动创建Servlet接口实现类的实例对象

    2. 在Http服务器运行期间,一个Servlet接口实现类只能被创建出一个实例对象,但是能被多次执行(即被URL访问多次)

    3. 在Http服务器关闭后,自动将网站中所有的Servlet对象进行销毁

    Servlet对象的创建时机 & load-on-startup配置参数

    1. "1.0" encoding="UTF-8"?>
    2. <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
    5. version="4.0">
    6. <servlet>
    7. <servlet-name>MyServletNameservlet-name>
    8. <servlet-class>controller.MyServletservlet-class>
    9. <load-on-startup>0load-on-startup>
    10. servlet>
    11. <servlet-mapping>
    12. <servlet-name>MyServletNameservlet-name>
    13. <url-pattern>/web1url-pattern>
    14. servlet-mapping>
    15. web-app>

    • Servlet对象的创建时机(即初始化的时机)

      • 若没有在web.xml给对应的Servlet对象配置 load-on-startup 参数,则容器一般在第一次响应web请求时创建对象,会先检测该servlet是否初始化,如未初始化,则调用servlet的init()先初始化,初始化成功后,再响应请求。

      • 若配置了 load-on-startup 参数,servlet将在Tomcat启动startup后立即创建对应实现类对象,但只是调用servlet的init()方法,用以初始化该servlet相关的资源。初始化成功后,该servlet可响应web请求

    • load-on-startup参数的作用

      • 标记容器是否在启动的时候就加载这个servlet。

      • 中间的数值必须是个整数

      • >=0时,表示容器在启动时就会初始化这个servlet类。数值越小优先级越高,加载的越早

        < 0时,表示当调用这个servlet类时才会将其实例化

      • 如果我们在web.xml中设置了多个servlet的时候,可以使用load-on-startup来指定servlet的加载顺序,服务器会根据load-on-startup的大小依次对servlet进行初始化。不过即使我们将load-on-startup设置重复也不会出现异常,服务器会自己决定初始化顺序

    验证 “Servlet对象只能被创建一次,但是能被多次调用” 和 验证load-on-startup确实能改变Servlet实现类的创建时机

    • init()方法可以理解为 Servlet实现类被创建时候的构造方法

    1. //src/controller/MyServlet.java
    2. public class MyServlet extends HttpServlet {
    3. //可以重写 init 方法,这个init方法代表对象被创建时候调用初始化。
    4. @Override
    5. public void init() throws ServletException {
    6. super.init();
    7. System.out.println("MyServlet对象被创建了");
    8. }
    9. @Override
    10. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    11. //...
    12. }
    13. }

    1. "1.0" encoding="UTF-8"?>
    2. <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
    5. version="4.0">
    6. <servlet>
    7. <servlet-name>MyServletNameservlet-name>
    8. <servlet-class>controller.MyServletservlet-class>
    9. <load-on-startup>0load-on-startup>
    10. servlet>
    11. <servlet-mapping>
    12. <servlet-name>MyServletNameservlet-name>
    13. <url-pattern>/web1url-pattern>
    14. servlet-mapping>
    15. web-app>

    验证结果:

    • 若该Servlet的web.xml配置中配置了 load-on-startup 参数为 >=0 的整数

      • 则点击运行Tomcat,发现立即输出了 “MyServlet对象被创建了”

      • 在网页URL中输入 /web1,发现输出了 “doGet中的代码执行结果”

      • 后续再多次在URL中访问 /web1,发现都可以输出doGet的执行结果,但是“MyServlet对象被创建了”再也没出现过

      • 上述现象说明Servlet对象只能被创建一次、但是可以被访问多次

        且还说明了若load-on-startup参数>=0,则Servlet实现类对象会在Tomcat启动时被立即创建

    • 若该Servlet的web.xml配置中没配置 load-on-startup 参数

      • 则点击运行Tomcat,发现什么都没输出(代表Servlet对象还没被初始化,即对象还没被创建)

      • 在网页URL中第一次输入 /web1,发现输出了 “MyServlet对象被创建了” 和 “doGet中的代码执行结果”

      • 上述现象说明Servlet对象若配置了 load-on-startup 参数,则会在Tomcat启动的时候就立即被创建,否则只会等到第一次用到的时候才创建

  • 相关阅读:
    【Vue】路由组件向app.vue主文件传值
    vue项目中页面跳转传参的方法
    JavaScript简介
    牛客题目——判断一个链表是否为回文结构、数据流中的中位数、PriorityQueue的常用方法
    Windows上使用client-go远程访问安装在本地WMware上的Linux虚拟机里的minikube
    CyNix
    Meta RGB透视VR研究:摄像头距离可调、分辨率720p
    基于大数据的企业岗位需求决策
    Spring 面向切面编程 第4关:AOP实现原理-CgLib动态代理
    CS从头配置电脑清单(软件篇)
  • 原文地址:https://blog.csdn.net/m0_57265007/article/details/128005739