Servlet 的运行原理

简介: Servlet 的运行原理

Servlet 运行原理


在 Servlet 的代码中我们并没有写 main 方法, 那么对应的 doGet 代码是如何被调用的呢? 响应又是如何返回给浏览器的?


一、Tomcat在Servlet运行中的定位


我们自己的实现是在 Tomcat 基础上运行的。当浏览器给服务器发送请求的时候 , Tomcat 作为 HTTP 服务器 , 就可以 接收到这个请求。

详细的交互过程示意图:

1667915822063.jpg

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);
相关文章
|
7月前
Servlet启动原理和原始运行方式
Servlet启动原理和原始运行方式
44 0
Servlet启动原理和原始运行方式
|
7月前
|
安全 Java 应用服务中间件
【JavaWeb】Tomcat底层机制和Servlet运行原理
网络通信:Tomcat使用Java的Socket API来监听特定的端口(通常是8080),接收来自客户端的HTTP请求。 线程池:Tomcat使用线程池来处理并发的请求。当有新的请求到达时,Tomcat会从线程池中获取一个空闲线程来处理该请求,这样可以提高处理效率。 生命周期管理:Tomcat负责管理Servlet和其他Web组件的生命周期,包括初始化、请求处理和销毁等阶段。(init(), run())
|
7月前
|
缓存 Java 数据库
Servlet 处理请求的原理
Servlet 处理请求的原理
175 0
|
8月前
|
Java API 容器
Servlet的执行原理和生命周期
Servlet的执行原理和生命周期
81 0
|
9月前
|
容器
Servlet原理
Servlet原理
40 0
|
10月前
|
Java 应用服务中间件
用IDEA创建servlet文件并用Tomcat运行
用IDEA创建servlet文件并用Tomcat运行
133 0
|
XML 数据格式
编译和运行 Servlet
编译和运行 Servlet
64 0
|
设计模式 安全 Java
【Tomcat技术专题】循序渐进,分析Servlet容器鼻祖的Server和Service组件原理
【Tomcat技术专题】循序渐进,分析Servlet容器鼻祖的Server和Service组件原理
130 0
【Tomcat技术专题】循序渐进,分析Servlet容器鼻祖的Server和Service组件原理
|
安全 Java 应用服务中间件
javaweb servlet体系结构与原理剖析
1.Servlet的工作过程 当用户通过 URL 发出一个请求时,这些 Java servlet 类就将之转换成一个 HttpServletRequest,并发送给 URL 所指向的目标。当服务器端完成其工作时,Java 运行时环境(JRE)就将结果包装在一个 HttpServletResponse 中,然后将原 HTTP 响应送回给发出该请求的客户机。 在与 Web 应用程序进行交互时,通常会发出多个请求并获得多个响应。所有这些都是在一个会话语境中,Java 语言将之包装在一个 HttpSession 对象中。在处理响应时,您可以访问该对象,并在创建响应时向其添加事件。它提供了一些跨请求的语
105 0
javaweb servlet体系结构与原理剖析
|
Java 应用服务中间件
使用最新版IDEA(21.3.2)创建一个最小的JAVAWEB应用(JSP,Servlet运行方法)
1.IDEA内创建一个基于Tomcat的项目 首先新建一个普通的项目
231 1
使用最新版IDEA(21.3.2)创建一个最小的JAVAWEB应用(JSP,Servlet运行方法)