从零手写实现 tomcat-04-请求和响应的抽象

创作缘由

平时使用 tomcat 等 web 服务器不可谓不多,但是一直一知半解。

于是想着自己实现一个简单版本,学习一下 tomcat 的精髓。

系列教程

从零手写实现 apache Tomcat-01-入门介绍

从零手写实现 apache Tomcat-02-web.xml 入门详细介绍

从零手写实现 tomcat-03-基本的 socket 实现

从零手写实现 tomcat-04-请求和响应的抽象

从零手写实现 tomcat-05-servlet 处理支持

从零手写实现 tomcat-06-servlet bio/thread/nio/netty 池化处理

从零手写实现 tomcat-07-war 如何解析处理三方的 war 包?

从零手写实现 tomcat-08-tomcat 如何与 springboot 集成?

从零手写实现 tomcat-09-servlet 处理类

从零手写实现 tomcat-10-static resource 静态资源文件

从零手写实现 tomcat-11-filter 过滤器

从零手写实现 tomcat-12-listener 监听器

整体思路

我们针对入参 request 和 出参 response 做一个简单的封装。

v1-出入参的抽象

request

    /*** 请求方式 例如:GET/POST*/private String method;/*** / , /index.html*/private String url;/*** 其他的属性都是通过inputStream解析出来的。*/private InputStream inputStream;public MiniCatRequest(InputStream inputStream) {this.inputStream = inputStream;this.readFromStream();}private void readFromStream() {try {//从输入流中获取请求信息int count = inputStream.available();byte[] bytes = new byte[count];int readResult = inputStream.read(bytes);String inputsStr = new String(bytes);logger.info("[MiniCat] readCount={}, input stream {}", readResult, inputsStr);//获取第一行数据String firstLineStr = inputsStr.split("\\n")[0];  //GET / HTTP/1.1String[] strings = firstLineStr.split(" ");this.method = strings[0];this.url = strings[1];} catch (IOException e) {logger.error("[MiniCat] readFromStream meet ex", e);throw new RuntimeException(e);}}

这里是针对 http 请求的解析处理。

response

    private final OutputStream outputStream;public MiniCatResponse(OutputStream outputStream) {this.outputStream = outputStream;}public void write(byte[] bytes) {try {outputStream.write(bytes);} catch (IOException e) {throw new MiniCatException(e);}}

start 方法调整

直接改动为对应的出入参对象。

while(runningFlag && !serverSocket.isClosed()){Socket socket = serverSocket.accept();// 输入流InputStream inputStream = socket.getInputStream();MiniCatRequest request = new MiniCatRequest(inputStream);// 输出流MiniCatResponse response = new MiniCatResponse(socket.getOutputStream());response.write(InnerHttpUtil.httpResp("Hello miniCat!").getBytes());socket.close();
}

测试

[INFO] [2024-04-02 16:27:32.455] [Thread-0] [c.g.h.m.b.MiniCatBootstrap.startSync] - [MiniCat] start listen on port 8080
[INFO] [2024-04-02 16:27:32.455] [Thread-0] [c.g.h.m.b.MiniCatBootstrap.startSync] - [MiniCat] visit url http://127.0.0.1:8080

我们浏览器访问 http://127.0.0.1:8080

读取到的流内容为:

[INFO] [2024-04-02 16:28:17.825] [Thread-0] [c.g.h.m.d.MiniCatRequest.readFromStream] - [MiniCat] readCount=664, input stream GET / HTTP/1.1
Host: 127.0.0.1:8080
Connection: keep-alive
sec-ch-ua: "Chromium";v="122", "Not(A:Brand";v="24", "Google Chrome";v="122"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: zh-CN,zh;q=0.9

v2-返回静态资源文件

思路

我们根据 url 解析本地的 html 等静态资源信息。

resources 下面的文件,mvn clean install 之后,默认在 ~\target\classes 路径下

核心代码

// 输出流
MiniCatResponse response = new MiniCatResponse(socket.getOutputStream());
// 判断文件是否存在
String staticHtmlPath = request.getUrl();
if (staticHtmlPath.endsWith(".html")) {String absolutePath = ResourceUtil.buildFullPath(ResourceUtil.getClassRootResource(MiniCatBootstrap.class), staticHtmlPath);String content = FileUtil.getFileContent(absolutePath);logger.info("[MiniCat] static html path: {}, content={}", absolutePath, content);String html = InnerHttpUtil.http200Resp(content);response.write(html);
} else {String html = InnerHttpUtil.http404Resp();response.write(html);
}

主要是两个步骤:

1)获取当前 class 文件对应的资源文件根路径。

2)然后拼接完整文件路径,读取文件内容。

测试

比如我们在 resource 下面放一个 index.html

内容如下:

mini cat index html!

启动后,访问:

访问 http://127.0.0.1:8080/index.html

页面返回:

mini cat index html!

开源地址

 /\_/\  
( o.o ) > ^ <

mini-cat 是简易版本的 tomcat 实现。别称【嗅虎】(心有猛虎,轻嗅蔷薇。)

开源地址:https://github.com/houbb/minicat

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/8279.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

什么是香草看涨期权?香草看涨期权有哪些特点?

什么是香草看涨期权&#xff1f;香草看涨期权有哪些特点&#xff1f; 香草看涨期权&#xff0c;通常也称为香草期权&#xff0c;是金融市场上的一种金融衍生品&#xff0c;由券商或金融机构推出。它允许投资者以较小的费用获取相应股票市值的收益权&#xff0c;主要用于风险管…

Python爬虫获取豆瓣电影Top100

大家好&#xff0c;我是秋意零。 今天分析一篇&#xff0c;Python爬虫获取豆瓣电影Top100。 在此之前&#xff0c;我没有学习过爬虫&#xff0c;只有一丢丢的Python基础。下面效果的实现源码几乎没经过我&#xff0c;而是AI百老师。我主要负责了对应的调试以及根据我想要的功…

5月7号(信息差)

&#x1f30d;首次&#xff0c;西湖大学用蛋白质语言模型定向改造碱基编辑器&#xff0c;登Cell子刊 https://www.jiqizhixin.com/articles/2024-05-07-10 &#x1f384; 哈马斯宣布同意停火提议 https://finance.eastmoney.com/a/202405073067687785.html ✨ 中国将对…

吴恩达机器学习笔记:第 9 周-16推荐系统(Recommender Systems) 16.3-16.4

目录 第 9 周 16、 推荐系统(Recommender Systems)16.3 协同过滤16.4 协同过滤算法 第 9 周 16、 推荐系统(Recommender Systems) 16.3 协同过滤 在之前的基于内容的推荐系统中&#xff0c;对于每一部电影&#xff0c;我们都掌握了可用的特征&#xff0c;使用这些特征训练出了…

推荐网站(6)33台词,通过台词找电影、电视剧、纪录片等素材

今天推荐一个网站33台词&#xff0c;你可以根据电影、电视剧、纪录片等某一段台词&#xff0c;来找到来源&#xff0c;帮你精确到多少分多少秒出现的&#xff0c;非常的好用&#xff0c;尤其是对那种只记得一些经典台词&#xff0c;不知道是哪个电影的人来说&#xff0c;帮助巨…

1W 3KVDC 隔离 单输出 DC/DC 电源模块 ——TPF 系列

TPF系列提供输出稳压&#xff0c;精度高&#xff0c;对于输出电压有要求的场合特别适合&#xff0c;工业级环境温度&#xff0c;用于PCB安装的国际标准结构。此系列产品小巧&#xff0c;效率高&#xff0c;低输出纹波及提供3000V以上的直流电压隔离&#xff0c;封装有SIP和DIP可…

网络安全之DHCP详解

DHCP&#xff1a;Dynamic Host Configration Protocol 动态主机配置协议 某一协议的数据是基于UDP封装的&#xff0c;当它想确保自己的可靠性时&#xff0c;这个协议要么选确认重传机制&#xff0c;要么选周期性传输。 DHCP是确认重传&#xff0c;【UDP|DHCP】,当DHCP分配完地…

零售全渠道营销业务链分析,让企业管控能力大幅加强!

对于传统的、规模化的零售快消企业来讲&#xff0c;面临着很大的渠道管理和建设问题&#xff0c;如何尽快实现整个营销体系的全渠道数字化转型是当务之急、重中之重。 面对错综分散的经销商&#xff0c;零售快消企业订货流程会越复杂&#xff0c;加之对门店管理较为粗放&#…

工业镜头助力锂电制造业精准检测

在电动汽车、电动轻型车、电动工具、消费电子和新型储能等行业大发展的背景下&#xff0c;锂电池综合优势与下游领域对电池大容量、高功率、使用寿命和环境保护日益提升的需求相契合&#xff0c;存在广阔的市场应用前景。受益于动力、消费和储能三大细分领域的快速发展&#xf…

spark history server异常

现象&#xff1a;spark 日志文件突然新增了很多.hprof文件&#xff0c; 查找日志spark配置参数spark_log_dir进入日志目录&#xff1a; 查看historyServer日志&#xff1a; Spark Command: /usr/lib/jvm/java-1.8.0/bin/java -cp /opt/apps/JINDOSDK/jindosdk-current/lib/*:/…

libcity 笔记:支持的模型

1 支持的模型 1.1 traffic_state_pred HA历史平均值&#xff0c;将历史流量建模为季节性过程&#xff0c;然后使用前几个季节的加权平均值作为预测值。VAR向量自回归SVR支持向量回归ARIMAAutoEncoderSeq2Seq采用基于门控循环单元的编码器-解码器框架&#xff0c;进行多步预测…

C++奇迹之旅:string类对象的修改操作

文章目录 &#x1f4dd;string类的常用接口&#x1f320; string类对象的修改操作&#x1f309;push_back&#x1f309;append&#x1f309;operator&#x1f309;insert&#x1f309;erase&#x1f309;replace&#x1f309; find&#x1f309; c_str &#x1f320;测试string…

大数据时代,如何准确查询并解读大数据信用报告?

在互联网时代&#xff0c;个人信息的安全和隐私保护愈发受到人们的关注。随着大数据技术的不断发展&#xff0c;越来越多的人开始关心自己的大数据报告。那么&#xff0c;如何找一个靠谱的地方查询个人大数据报告呢?本文将为您详细解答。 一、先了解大数据报告的含义 首先&…

四、 现行数据出境制度下的三条合规路径是什么?如何判断?

综合《网络安全法》《数据安全法》以及《个人信息保护法》这三大数据合规基本法律要求来看&#xff0c;企业开展数据出境活动时&#xff0c;应结合自身的主体类型、出境数据类型和数量&#xff0c;综合判断是否须要额外&#xff08;1&#xff09;申报并通过数据出境安全评估&am…

ASIL详解

概念 随着汽车新四化的发展&#xff0c;整车E/E系统的复杂性也不断增加&#xff0c;功能安全正成为一种更主流的要求。汽车安全完整性等级&#xff08;ASIL&#xff09;分解为实现更高水平的诊断覆盖度提供了可靠而稳健的途径&#xff0c;并在开发具有更高ASIL等级的安全关键系…

HDMI2.0一分四的方案 推荐使用教程如下:

符合HDMI2.0b和HDCP2.2标准 向后兼容HDMI1.4、HDCP1.X标准 支持RGB和YCbCr 444/422/420格式 支持CSC&#xff08;颜色空间转换&#xff09;矩阵和420/422/444转换&#xff08;1:1&#xff1b; 1:2&#xff1b;2:1&#xff09; 在传统显示器上&#xff0c;支持4:1向下缩放4K…

基于卷积神经网络的信号解卷积(简单版,MATLAB)

简单演示一下基于卷积神经网络的信号解卷积&#xff0c;有个大致印象即可。 构造卷积滤波器 r 0.9; % Define filter om 0.95; a [1 -2*r*cos(om) r^2]; b [1 r*cos(om)]; h filter(b, a, [zeros(1,38) 1 zeros(1,40)]); N 500; K 25; sigma 1; 绘制输入信号分量 s…

LabelImg下载及目标检测数据标注

为什么这一部分内容这么少会单独拎出来呢&#xff0c;因为后期会接着介绍YOLOv8中的其他任务&#xff0c;会使用其他软件进行标注&#xff0c;所以就单独区分开来每一个任务的标注方式了。 这一部分就介绍目标检测任务的标注&#xff0c;数据集是我从COCO2017Val中抽出来两类&a…

【Nginx】the “listen ... http2“ directive is deprecated

今天安装了 1.26.0 版本的Nginx&#xff0c;执行nginx -t命令时报了如下错误&#xff1a; nginx: [warn] the "listen ... http2" directive is deprecated, use the "http2" directive instead报这个错误的原因是&#xff0c;Nginx 自从 1.25 版本后&…

移动端自动化测试工具 Appium 之元素操作小技巧

文章目录 一、背景二、TestNG常用注解三、实战3.1、集成启动类3.2、采用xpath定位元素3.3、编写通用判断类3.4、编写测试类3.5、遍历实现 四、总结 一、背景 appium自动化工作中&#xff0c;元素操作最常用的就是Id/xpath&#xff0c;因为【appium1.5.0后&#xff0c;不支持使…