手把手带你写一个 MiniTomcat
郭屹
前 Sun Microsystems Java 研发工程师
1792 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 22 讲
开篇词 (1讲)
手把手带你写一个 MiniTomcat
15
15
1.0x
00:00/00:00
登录|注册

06|规范化:引入HttpRequest与HttpResponse

你好,我是郭屹。今天我们继续手写 MiniTomcat。
在前面的学习结束之后,我们引入了池化技术,还实现 Processor 的异步化。前者复用对象,减少构造新对象的时间开销;后者使 Connector 能同时服务于多个 Processor。这些都是提升性能和吞吐量的常用技术手段。
这节课我们继续研究 Servlet 规范,对我们现有的代码进行改造,使之适配这个规范。同时我们还要解析 HTTP 协议中的请求信息,并把它存储到服务器内存之中。
下面就让我们一起来动手实现。

项目结构

这节课因为需要进行 Servlet 规范适配工作,还要解析头部信息,因此会新增几个类,整体结构如下:
MiniTomcat
├─ src
│ ├─ main
│ │ ├─ java
│ │ │ ├─ server
│ │ │ │ ├─ DefaultHeaders.java
│ │ │ │ ├─ HttpConnector.java
│ │ │ │ ├─ HttpHeader.java
│ │ │ │ ├─ HttpProcessor.java
│ │ │ │ ├─ HttpRequest.java
│ │ │ │ ├─ HttpRequestLine.java
│ │ │ │ ├─ HttpResponse.java
│ │ │ │ ├─ HttpServer.java
│ │ │ │ ├─ Request.java
│ │ │ │ ├─ Response.java
│ │ │ │ ├─ ServletProcessor.java
│ │ │ │ ├─ SocketInputStream.java
│ │ │ │ ├─ StatisResourceProcessor.java
│ │ ├─ resources
│ ├─ test
│ │ ├─ java
│ │ │ ├─ test
│ │ │ │ ├─ HelloServlet.java
│ │ ├─ resources
├─ webroot
│ ├─ test
│ │ ├─ HelloServlet.class
│ ├─ hello.txt
├─ pom.xml
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入介绍了在手写MiniTomcat的过程中引入HttpRequest与HttpResponse的规范化工作。作者首先详细讲解了对Servlet规范的适配工作,包括实现HttpServletRequest与HttpServletResponse接口的过程。通过对SocketInputStream中定义的方法,读者可以了解到如何从输入流中读出request line和header信息。文章还介绍了在解析Request信息时的一些技术细节,如char数组的使用、indexOf()方法的实现等。通过本文,读者可以了解到在实现HttpRequest与HttpResponse的过程中涉及的技术细节和实现方法,对于想要了解Servlet规范适配工作和实现HttpRequest与HttpResponse接口的读者来说,具有很高的参考价值。文章还介绍了在解析Request信息时的一些技术细节,如char数组的使用、indexOf()方法的实现等。通过本文,读者可以了解到在实现HttpRequest与HttpResponse的过程中涉及的技术细节和实现方法,对于想要了解Servlet规范适配工作和实现HttpRequest与HttpResponse接口的读者来说,具有很高的参考价值。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《手把手带你写一个 MiniTomcat》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(4)

  • 最新
  • 精选
  • C.
    buf[pos++]:表示buf的pos索引加一,以便后续read操作,是个后缀递增的操作。 & 0xff:位操作,字节在Java的中的范围为-128到127,是个有符号数,执行& 0xff是在做一个按位与操作,转换为一个无符号数,返回的值在0-255。0xff等于十进制的255,二进制位11111111。buf[pos]字节会与11111111进行按位与操作,基本保持了原始字节的值不变。

    作者回复: 你说的是对的。我用自己的语言组织一下: byte转int或者char的时候, 如果byte原本是正数,补零扩展是没有问题的。 但是对于负数的情况,高位会补1,造成二进制补码不一致,所以用&0xff 将高位补零,低8位保持原样,这样二进制补码是一致的。

    2023-12-20归属地:江苏
    2
    3
  • Clark Chen
    老师好, 关于`SocketInputStream .readRequestLine(HttpRequestLine requestLine)` 方法的这段代码 ``` while (!space) { if (pos >= count) { int val = read(); if (val == -1) { throw new IOException("requestStream.readline.error"); } pos = 0; readStart = 0; } if (buf[pos] == SP) { space = true; } requestLine.method[readCount] = (char) buf[pos]; readCount++; pos++; } ``` 有些地方没想明白, 为什么要在这个方法里面对手动控制pos++,直接获取buf[]里面的值 ,而不是通过read 方法来获取值。如下面这样 ``` while (!space){ if(pos >= count ){ readStart = 0; } int val = read(); if(val == -1){ throw new IOException("requestStream.readline.error"); } if(val == SP){ space =true; } requestLine.getMethod()[readCount] = (char)val; readCount++; } ``` 是有效率上的原因吗?

    作者回复: 对,我的理解就是效率上的原因。

    2023-12-24归属地:辽宁
    1
  • peter
    请教老师两个问题: Q1:parameters用来做什么? HttpRequest类中定义了parameters,但好像并没有使用,这个类是用来存什么的? Q2:parseHeaders函数用if区分有意义吗? HttpRequest类中的parseHeaders用if … else来区分各个部分,但其实最后都是调用headers.put(name, value); 所有的分支,最后的处理结果都是一样的,这个区分还有意义吗?

    作者回复: if是用来处理特殊header的,如果不是这些特殊的header,统一put

    2023-12-20归属地:北京
  • HH🐷🐠
    😄感觉像是纠正什么数据

    作者回复: byte转int或者char的时候, 如果byte原本是正数,补零扩展是没有问题的。 但是对于负数的情况,高位会补1,造成二进制补码不一致,所以用&0xff 将高位补零,低8位保持原样,这样二进制补码是一致的。

    2023-12-20归属地:广东
收起评论
显示
设置
留言
4
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部