栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

03【HowTomcatWork】手写一个连接器,更完整的http请求、响应包的处理过程

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

03【HowTomcatWork】手写一个连接器,更完整的http请求、响应包的处理过程

代码仓库
本节对应05-connector

文章目录
  • 本节概述
  • 处理请求
  • 响应处理
  • 响应到达servlet

本节概述

05-connector中,我们把之前写的 HttpServer 类被分离为两个类:HttpConnector和 HttpProcessor

之前的 HttpServer类的职责是【等待 HTTP 请求】并【创建请求和响应对象】。
在本章的应用中,等待 HTTP 请求的工作交给 HttpConnector 实例,而创建请求和响应对象的工作交给了HttpProcessor 实例。

以前,我的请求类是实现了javax.servlet.ServletRequest接口的Request类。
本章中,我的请求类是实现了 javax.servlet.http.HttpServletRequest 接口的 HttpRequest类。

【http请求包中的信息被解析后】会封装成一个 HttpRequest 对象,它会被转换为一个 HttpRequestFacade 实例, 传递给 servlet 的 service 方法。

解析一个 HTTP请求牵涉昂贵的字符串和其他操作,假如只是解析 servlet 需要的值的话,连接器就能节省许多 CPU 周期。
本章自己写的HttpConnector连接器和【Tomcat的默认连接器】试图不解析请求参数,直到 servlet 真正需要它的时候再解析,通过这样来获得更高效率。后文解释。

处理请求

05-connector模块中,我写了一个HttpProcessor类, 它使用SocketInputStream类来从套接字的InputStream中读取字节流。一个 SocketInputStream 实例对【从套接字的 getInputStream 方法中返回的java.io.InputStream 实例】进行包装。

SocketInputStream 类提供了两个重要的方法:readRequestLine 和 readHeader。
readRequestLine读取请求行,readHeader读取请求头
我们知道一个http请求分为请求行,请求头,请求空行和请求体。

readRequestLine 返回一个 HTTP 请求的第一行。例如,这行包括了 URI,方法和 HTTP 版本,这些信息封装在HttpRequestLine对象中。

readHeader每次被调用来获得【一个请求头的键值对】,这1个键值对的被封装成HttpHeader对象,并且应该被重复的调用直到所有的请求头键值对被读取到。

下图是访问【http://localhost:8090/index.html?name=cy&age=20】经过解析后的HttpRequest对象。HttpRequest对象大多数信息都存在了,但是请求参数还没有解析。

啥时候解析请求参数?
当getParameter方法被调用 ,会解析请求参数
我们可以在servlet的service方法中调用getParameter方法

解析参数的过程分2步

响应处理

原来我们通过socket.getOutputStream() 得到一个java.net.SocketOutputStream对象,用它的write()方法发送字节数据。

后来我们做了一定优化,将java.net.SocketOutputStream对象包装成java.io.PrintWriter对象发送数据

java.io.PrintWriter对象有一个bool属性autoFlush
autoFlush为true:println、printf、format方法调用后会自动清除缓冲区

如果是一次servlet请求,我们应该先通过【response.sendHeaders()】发送响应行,响应头,响应空行的数据

public void sendHeaders()
和之前直接将java.net.SocketOutputStream对象包装成java.io.PrintWriter对象不同
我们这里指定了字符集

发送响应行、响应头

响应到达servlet

之前已经发送响应行、响应头、响应空行
在servlet中,我们也使用PrintWriter继续向【响应体】写数据,当访问地址
http://localhost:8090/servlet/PrimitiveServlet?name=cy
控制台会输出cy, 浏览器显示Hello

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/690935.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号