Tomcat的处理请求流程详解

本文揭示了Tomcat如何解析字节流并依据HTTP协议处理请求,探讨了Servlet容器Engine、Host、Context和Wrapper的作用及它们之间的层次关系。重点讲解了请求解析过程和Servlet实例调用机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Tomcat启动后,在接收到某个请求后,就可以根据请求路径和url-pattern进行匹配,如果匹配成功,则会把这个请求交给对应的servlet进行处理。

大致的处理流程中的问题:

1、tomcat如何解析字节流
2、tomcat把解析出来的httpServletRequests对象,是如何到servlet的,调用了哪些方法,如何调用的。

处理流程简述:

  1. 浏览器在请求一个Servlet时,会按照HTTP协议构造一个HTTP请求,通过Socket连接发送给Tomcat
  2. Tomcat通过不同的IO模型都可以接收到Socket的字节流数据
  3. 接收到数据后,按HTTP协议解析字节流,得到HttpServletRequest对象
  4. 再通过HttpServletRequest对象,也就是请求信息,找到该请求对应的Host、Context、Wrapper
  5. 然后将请求交给Engine层处理
  6. Engine层处理完,就会将请求交给Host层处理
  7. Host层处理完,就会将请求交给Context层处理
  8. Context层处理完,就会将请求交给Wrapper层处理
  9. Wrapper层在拿到一个请求后,就会生成一个请求所要访问的Servlet实例对象
  10. 调用Servlet实例对象的service()方法,并把HttpServletRequest对象当做入参
  11. 从而就调用到Servlet所定义的逻辑

问题一:

Tomcat是如何根据HTTP协议来解析字节流的。

获取字节流

Tomcat底层是通过TCP协议,也就是Socket来获取网络数据的,那么从Socket上获取数据,就涉及到IO模型,在Tomcat8以后,就同时支持了NIO和BIO。

在Tomcat中,有一个组件叫做Connector,他就是专门用来接收Socket连接的,在Connector内部有一个组件叫ProtocolHandler,它有好几种实现:
Http11Protocol
Http11NioProtocol
Http11AprProtocol

解析字节流

不同的IO模型只是表示从Socket上获取字节流的方式不同而已,而获取到字节流之后,就需要进行解析了,之前我们说过,Tomcat需要按照HTTP协议的格式来解析字节流,下面是HTTP协议的格式:

在这里插入图片描述
所以,浏览器或者HttpClient在发送数据时,同样需要按照Http协议来构造数据(字符串),然后将字符串转成字节发送出去,所以Tomcat解析字节流的逻辑就是:

从获得的第一个字节开始,遍历每个字节,当遇到空格时,那么之前所遍历到的字节数据就是请求方法

然后继续遍历每个字节,当遇到空格时,那么之前遍历到的字节数据就是URL

然后继续遍历每个字节,当遇到回车、换行符时,那么之前遍历到的字节数据就是协议版本,并且表示请求行遍历结束

然后继续遍历当遇到一个回车符和换行符时,那么所遍历的数据就是一个请求头

继续遍历当遍历到两个回车符和换行符时,那么所遍历的数据就是一个请求头,并且表示请求头全部遍历完毕

剩下的字节流数据就表示请求体

值得注意的是,如果使用的是长连接,那么就有可能多个HTTP请求共用一个Socket连接,那么Tomcat在获取并解析Socket连接中的字节流时,该如何判断某个HTTP请求的数据在哪个位置结束了呢?也就是如何判断一个请求的请求体何时结束?

有两种方式:

  1. 设置Content-Length:在发送请求时直接设置请求体的长度,那么Tomcat在解析时,自然就知道了当前请求的请求体在哪个字节结束

  2. 设置Transfer-Encoding为chunk:也就是分块传输,在发送请求时,按如下格式来传输请求体,[chunk
    size][\r\n][chunk data][\r\n][chunk size][\r\n][chunk
    data][\r\n][chunk size = 0][\r\n][\r\n],注意最后的chunk
    size=0和两个回车换行符,只要Tomcat解析到这些时,就表示接收到了最后一块,也就表示请求体结束了

问题二

在Tomcat中存在四大Servlet容器:

  • Engine:直接理解为一个Tomcat即可,一个Tomcat一个Engine

  • Host:一个Host表示一个虚拟服务器,可以给每个Host配置一个域名

  • Context:一个Context就是一个应用,一个项目

  • Wrapper:一个Wrapper表示一个Servlet的包装,Wrapper在后文详解

并且这四个Servlet容器是具有层次关系的:一个Engine下可以有多个Host,一个Host下可以有多个Context,一个Context下可以有多个Wrapper,一个Wrapper下可以有多个Servlet实例对象。

Tomcat接收到某个请求后,首先会判断该请求的域名,根据域名找到对应的Host对象,Host对象再根据请求信息找到请求所要访问的应用,也就是找到一个Context对象,Context对象拿到请求后,会根据请求信息找到对应的Servlet,那么Wrapper是什么?

我们定义的某个Servlet,在Tomcat中可能会存在多个该类型的实例对象,所以Tomcat需要再抽象出来一层,这一层就是Wrapper,一个Wrapper对应一个Servlet类型,Wrapper中有一个集合,用来存储该Wrapper对应的Servlet类型的实例对象。
在这里插入图片描述
四大容器的作用:

Engine:可以处理Tomcat所接收到所有请求,不管这些请求是请求哪个应用或哪个Servlet的。

Host:可以处理某个特定域名的所有请求

Context:可以处理某个应用的所有请求

Wrapper:可以处理某个Servlet的所有请求

在这里插入图片描述

参考资料:

https://www.bilibili.com/read/cv11646372

https://www.bilibili.com/read/cv11646413?spm_id_from=333.999.0.0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值