提问:从 0 开始手写一个Tomcat

Tomcat是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,也是一个servlet容器的优秀解决方案(它还是一个满足 Servlet 规范的容器)

一、Tomcat 和我们的 Web 应用是什么关系

我们一般需要把 Web 应用打成 WAR 包部署到 Tomcat 中,在我们的 Web 应用中,我们要指明 URL 被哪个类的哪个方法所处理「不论是原始的 Servlet 开发,还是现在流行的 Spring MVC 都必须指明」。
由于我们的 Web 应用是运行在 Tomcat 中,那么显然,请求必定是先到达Tomcat 的。Tomcat 对于请求实际上会进行如下的处理。

1.1 提供Socket服务,监听客户端端口号

在客户/服务器通信模式中, 服务器端需要创建监听端口的 ServerSocket, ServerSocket 负责接收客户连接请求,先创建一个ServerSocket,例如:

ServerSocket serverSocket = null;
   int port = 80;
   try {
     serverSocket =  new ServerSocket(port, 1, InetAddress.getByName("127.0.0.1"));
   }
   catch (IOException e) {
     e.printStackTrace();
     System.exit(1);
   }

为了方便测试,我设置接听了localhost的80端口,socketServer能时刻待命,接收来自客户端的连接请求,socketServer的实现使用了连接池和线程池,不过具体的实现不在本文讨论范围,有需要的朋友可以自行研究.

1.2 接收到客户请求后serverSocket会返回一个socket实例,然后获取InputStream和OutPutStream

 socket = serverSocket.accept();
 input = socket.getInputStream();
 output = socket.getOutputStream();

1.3 然后件inputStream流解析成request,当然这个request还是很原始的request,获取请求里面的uri,解析之后将request传入response

Request request = new Request(input);
request.parse();
 
Response response = new Response(output);
response.setRequest(request);
response.sendStaticResource();
 
socket.close();

1.4 request从流中读取信息,并在请求行中解析出请求的uri

如:GET index.html HTTP/1.1 ,uri就会被设置成index.html,在项目的根目录创建一个webroot的文件夹,创建一个index.html文件,uri和这个文件名要对应。
在response中,将读取本地的webroot文件夹的request的uri对应名字的文件,通过socket的outputStream发送给客户端:

public void sendStaticResource() throws IOException {
  byte[] bytes = new byte[BUFFER_SIZE];
  FileInputStream fis = null;
  try {
    File file = new File(HttpServer.WEB_ROOT, request.getUri());
    if (file.exists()) {
      fis = new FileInputStream(file);
      int ch = fis.read(bytes, 0, BUFFER_SIZE);
      while (ch!=-1) {
        output.write(bytes, 0, ch);
        ch = fis.read(bytes, 0, BUFFER_SIZE);
      }
    }
    else {
      // file not found
      String errorMessage = "HTTP/1.1 404 File Not Found\r\n" +
        "Content-Type: text/html\r\n" +
        "Content-Length: 23\r\n" +
        "\r\n" +
        "<h1>File Not Found</h1>";
      output.write(errorMessage.getBytes());
    }
  }
  catch (Exception e) {
    // thrown if cannot instantiate a File object
    System.out.println(e.toString() );
  }
  finally {
    if (fis!=null)
      fis.close();
  }
}

运行httpServer的main方法,然后打开浏览器,输入localhost/index.html
在这里插入图片描述
参考:从零开始写一个静态Tomcat(壹)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值