手写迷你版 Tomcat - Minicat

Posted 景禹

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手写迷你版 Tomcat - Minicat相关的知识,希望对你有一定的参考价值。

手写迷你版 Tomcat - Minicat

原文连接:https://notes.suremotoo.site/archives/handwriting-minicat

手写简单版本的 tomcat 的意义是,有助于大家对 HTTP 协议的理解,增加对 tomcat 开源服务器的理解。

本文中对 servlet 的支持比较复杂,大家可以依赖 javax.servlet 来对servlet 程序进行支持,此外可以考虑增加对于长连接的支持和解析。

Minicat 的目标

我们可以通过浏览器客户端发送 http 请求, Minicat 可以接收到请求进⾏处理,处理之后的结果可以返回浏览器客户端。

基本方向

  • 提供服务,接收请求(Socket 通信)
  • 请求信息封装成 Request 对象,同样响应信息封装成 Response 对象
  • 客户端请求资源,资源分为静态资源(html)和动态资源(Servlet)
  • 资源返回给客户端浏览器

迭代实现

我们实现时候呢,一步一步来,可以制定的小版本计划

  • V1.0 需求:浏览器请求 http://localhost:8080, 返回⼀个固定的字符串到⻚⾯"Hello Minicat."
  • V2.0 需求:封装 Request 和 Response 对象,返回 HTML 静态资源⽂件
  • V3.0 需求:可以请求动态资源(Servlet)
  • V4.0 需求:可以多线程访问
  • V5.0 需求:在已有 Minicat 基础上进⼀步扩展,模拟出 webapps 部署效果,磁盘上放置⼀个 webapps ⽬录,webapps 中可以有多个项⽬,⽐如 demo1,demo2,demo3… 具体的项⽬⽐如 demo1 中有 serlvet(也即为:servlet 是属于具体某⼀个项⽬的 servlet),这样的话在 Minicat 初始化配置加载,以及根据请求 url 查找对应 serlvet 时都需要进⼀步处理。

V1.0 版本

环境搭建

确定好方向,就进行项目搭建开发

新建一个 Maven 项目,并调整在 pom.xml

  <groupId>site.suremotoo</groupId>
  <artifactId>Minicat</artifactId>
  <version>1.0-SNAPSHOT</version>
  <build>
      <plugins>
          <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-compiler-plugin</artifactId>
              <version>3.1</version>
              <configuration>
                  <source>11</source>
                  <target>11</target>
                  <encoding>utf-8</encoding>
              </configuration>
          </plugin>
      </plugins>
  </build>

编写启动类 Bootstrap

public class Bootstrap {

  /**
   * 设定启动和监听端口
   */

  private int port = 8080;

  /**
   * 启动函数
   *
   * @throws IOException
   */

  public void start() throws IOException {
      System.out.println("Minicat starting...");
      String responseData = "Hello Minicat.";
      ServerSocket socket = new ServerSocket(port);
      while (true) {
          Socket accept = socket.accept();
          OutputStream outputStream = accept.getOutputStream();
          String responseText = HttpProtocolUtil.getHttpHeader200(responseData.length()) + responseData;
          outputStream.write(responseText.getBytes());
          accept.close();
      }
  }

  /**
   * 启动入口
   *
   * @param args
   */

  public static void main(String[] args) throws IOException {
      Bootstrap bootstrap = new Bootstrap();
      bootstrap.start();
  }

}

HTTP 协议辅助类 HttpProtocolUtil

public class HttpProtocolUtil {

    /**
     * 200 状态码,头信息
     *
     * @param contentLength 响应信息长度
     * @return 200 header info
     */

    public static String getHttpHeader200(long contentLength) {
        return "HTTP/1.1 200 OK \n" + "Content-Type: text/html \n"
                + "Content-Length: " + contentLength + " \n" + "\r\n";
    }

    /**
     * 为响应码 404 提供请求头信息(此处也包含了数据内容)
     *
     * @return 404 header info
     */

    public static String getHttpHeader404() {
        String str404 = "<h1>404 not found</h1>";
        return "HTTP/1.1 404 NOT Found \n" + "Content-Type: text/html \n"
                + "Content-Length: " + str404.getBytes().length + " \n" + "\r\n" + str404;
    }

}

然后我们访问浏览器:http://localhost:8080,页面显示 Hello Minicat.,就说明成功啦。

这就完成 V1.0 版本了

以上是关于手写迷你版 Tomcat - Minicat的主要内容,如果未能解决你的问题,请参考以下文章

tomcat学习笔记手写tomcat

tomcat学习笔记手写tomcat

手写一个迷你版Spring MVC框架

手写迷你版hashmap

react源码解析19.手写迷你版react

react源码解析19.手写迷你版react