Servlet 的运行原理

导读:本篇文章讲解 Servlet 的运行原理,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

系列文章目录

如何创建一个Servlet项目(Maven)?_crazy_xieyi的博客-CSDN博客

Tomcat下载、安装及使用介绍_crazy_xieyi的博客-CSDN博客


文章目录

  • Tomcat在Servlet运行中的定位
    • 1. 接收请求:
    • 2.根据请求计算响应
    • 3.返回响应
  • 二、Tomcat 是如何初始化/处理请求的?
  •      
    1.Tomcat 初始化
  •      2.Tomcat 处理请求
  •      3.Servlet 的 service 方法

 

Servlet 运行原理

在 Servlet 的代码中我们并没有写 main 方法, 那么对应的 doGet 代码是如何被调用的呢? 响应又是如何返回给浏览器的?
 
Tomcat在Servlet运行中的定位
 
我们自己的实现是在 Tomcat 基础上运行的。当浏览器给服务器发送请求的时候, Tomcat 作为 HTTP 服务器, 就可以
接收到这个请求。
 
详细的交互过程示意图:
55105e436ef44c10bd5ec63ffd96002b.png
1) 接收请求:
用户在浏览器输入一个 URL, 此时浏览器就会构造一个 HTTP 请求。
这个 HTTP 请求会经过网络协议栈逐层进行
封装 成二进制的 bit 流, 最终通过物理层的硬件设备转
换成光信号/电信号传输出去。
这些承载信息的光信号/电信号通过互联网上的一系列网络设备, 最终到达目标主机(这个过程也需
要网络层和数据链路层参与)。
服务器主机收到这些光信号/电信号, 又会通过网络协议栈逐层进行
分用, 层层解析, 最终还原成
HTTP 请求。并交给 Tomcat 进程进行处理(根据端口号确定进程)。
Tomcat 通过 Socket 读取到这个请求(一个字符串), 并按照 HTTP 请求的格式来解析这个请求, 根据
请求中的 Context Path 确定一个 webapp, 再通过 Servlet Path 确定一个具体的 类. 再根据当前请
求的方法 (GET/POST/…), 决定调用这个类的 doGet 或者 doPost 等方法. 此时我们的代码中的
doGet / doPost 方法的第一个参数 HttpServletRequest 就包含了这个 HTTP 请求的详细信息。
 
2) 根据请求计算响应:
在我们的 doGet / doPost 方法中, 就执行到了我们自己的代码。我们自己的代码会根据请求中的一
些信息, 来给 HttpServletResponse 对象设置一些属性. 例如状态码, header, body 等。
 
3) 返回响应:
我们的 doGet / doPost 执行完毕后, Tomcat 就会自动把 HttpServletResponse 这个我们刚设置
好的对象转换成一个符合 HTTP 协议的字符串, 通过 Socket 把这个响应发送出去。
此时响应数据在服务器的主机上通过网络协议栈层层
封装, 最终又得到一个二进制的 bit 流, 通过
物理层硬件设备转换成光信号/电信号传输出去。
这些承载信息的光信号/电信号通过互联网上的一系列网络设备, 最终到达浏览器所在的主机(这个
过程也需要网络层和数据链路层参与)。
浏览器主机收到这些光信号/电信号, 又会通过网络协议栈逐层进行
分用, 层层解析, 最终还原成
HTTP 响应, 并交给浏览器处理。
浏览器也通过 Socket 读到这个响应(一个字符串), 按照 HTTP 响应的格式来解析这个响应. 并且把
body 中的数据按照一定的格式显示在浏览器的界面上。
 
 

 

二、Tomcat 是如何初始化/处理请求的?
 
     
1.Tomcat 初始化
 
Tomcat 的代码中内置了 main 方法. 当我们启动 Tomcat 的时候, 就是从 Tomcat 的 main 方法开
始执行的。
 
被 @WebServlet 注解修饰的类会在 Tomcat 启动的时候就被获取到, 并集中管理。
 
Tomcat 通过
反射 这样的语法机制来创建被 @WebServlet 注解修饰的类的实例。
 
这些实例被创建完了之后, 会调用其中的 init 方法进行初始化. (这个方法是 HttpServlet 自带的,
我们自己写的类可以重写 init)。
 
这些实例被销毁之前, 会调用其中的 destory 方法进行收尾工作. (这个方法是 HttpServlet 自带的,
我们自己写的类可以重写 destory)。
 
Tomcat 内部也是通过 Socket API 进行网络通信。
 
Tomcat 为了能同时相应多个 HTTP 请求, 采取了多线程的方式实现. 因此 Servlet 是运行在
多线程
环境 下的。
 

     2.Tomcat 处理请求

Tomcat 从 Socket 中读到的 HTTP 请求是一个字符串, 然后会按照 HTTP 协议的格式解析成一个
HttpServletRequest 对象。
 
Tomcat 会根据 URL 中的 path 判定这个请求是请求一个静态资源还是动态资源. 如果是静态资源,
直接找到对应的文件把文件的内容通过 Socket 返回. 如果是动态资源, 才会执行到 Servlet 的相关
逻辑。
 
Tomcat 会根据 URL 中的 Context Path 和 Servlet Path 确定要调用哪个 Servlet 实例的 service
方法。
通过 service 方法, 就会进一步调用到我们之前写的 doGet 或者 doPost。
 

     3.Servlet 的 service 方法

Servlet 的 service 方法内部会根据当前请求的方法, 决定调用其中的某个 doXXX 方法。
 

在调用 doXXX 方法的时候, 就会触发 多态 机制, 从而执行到我们自己写的子类中的 doXXX 方法。

自己写的类, 继承自 HttpServlet 类. 而 HttpServlet 又继承自 Servlet. 相当于自己写的类就是Servlet 的子类。接下来, 在 Tomcat 启动阶段, Tomcat 已经根据注解的描述, 创建了 自己写的类 的实例, 然后把这个实例放到了 Servlet 数组中。后面我们根据请求的 URL 从数组中获取到了该实例, 但是我们是通过 Servlet ins这样的父类引用来获取到该实例的。

最后, 我们通过 ins.doGet() 这样的代码调用 doGet 的时候, 正是 “父类引用指向子类对象”, 此
时就会触发多态机制, 从而调用到我们之前写的类中所实现的 doGet 方法。
等价代码:
Servlet ins = new HelloServlet();
ins.doGet(req, resp);

 


 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/94579.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!