码迷,mamicode.com
首页 > Web开发 > 详细

理解tomcat之搭建简易http服务器

时间:2017-04-23 23:14:48      阅读:253      评论:0      收藏:0      [点我收藏+]

标签:request   service   冰山一角   服务器   工作原理   

 做过java web的同学都对tomcat非常熟悉。我们在使用tomcat带来的便利的同时,是否想过tomcat是如何工作的呢?tomcat本质是一个http服务器,本篇文章将搭建一个简单的http服务器。

1 Catalina模型

   首先我们先了解一下tomcat的大致工作原理。tomcat的核心是servlet容器,我们称它为Catalina(为什么叫这个名字?我也不知道 ̄へ ̄)。模型图如1.1

     技术分享

                                        图1.1

    Connector是用来“连接”容器里边的请求的。它的工作是为接收到每一个 HTTP 请求构造一个 request 和 response 对象。然后它把流程传递给容器。容器从连接器接收到 requset 和 response 对象之后调用 servlet 的 service 方法用于响应。谨记,这个描述仅仅是冰山一角而已。这里容器做了相当多事情。例如,在它调用 servlet 的 service 方法之前,它必须加载这个 servlet,验证用户(假如需要的话),更新用户会话等等。以此为思路,我们就开始我们的构造http服务器之旅吧。

2 服务器搭建

  首先我们明确一下我们的服务器的功能点。

  1. 需要有一个类去接收http请求;

  2. 需要一个自定义Request类和Response类,把接收到的请求构造成这两个类;

  3. 根据请求的格式来确定处理方式:返回静态资源 or 进入Servlet ?

  4. 需要一个Servlet类执行业务逻辑

  UML图如下2.1

  技术分享  

                                     图2.1

2.1 HttpServer 

首先构造HttpServer类

技术分享 View Code

  我们的服务器启动入口放在了HttpServer里面。await()方法负责接收Socket连接,只有当用户输入了代表shutdown的URL时,服务器才会停止运行。Request类提供了解析请求的功能,根据请求的url,来决定是返回静态资源,或者进入对应的servlet类执行service逻辑。

    这里我们需要关注一下ServerSocket这个类的用法。Socket 类代表一个客户端套接字,即任何时候你想连接到一个远程服务器应用的时候,你都会第一时间想到这个类。而ServerSocket 和 Socket 不同,服务器套接字的角色是等待来自客户端的连接请求。一旦服 务器套接字获得一个连接请求,它创建一个 Socket 实例来与客户端进行通信。 ServletSocket套接字的其中一个构造函数为

public ServerSocket(int port, int backLog, InetAddress bindingAddress); 

    port代表端口号,backLog代表这个套接字可支持的最大连接数量,bindingAddress代表服务器绑定的地址。一旦你有一个 ServerSocket 实例,你可以通过调用 ServerSocket 类的 accept 方法j。这个监听当前地址的当前端口上的请求,方法只会在有连接请求时才会返回,并且返回值是一个 Socket 类的实例。

2.2 Request Response

     servlet 的 service 方法从 servlet 容器中接收一个 javax.servlet.ServletRequest 实例 和一个 javax.servlet.ServletResponse 实例。这就是说对于每一个 HTTP 请求,servlet 容器 必须构造一个 ServletRequest 对象和一个 ServletResponse 对象并把它们传递给正在服务的 servlet 的 service 方法。 

 

技术分享 View Code

     Request类代表一个 request 对象并被传递给 servlet 的 service 方法。就本身而言,它必须实现 javax.servlet.ServletRequest 接口。这个类必须提供这个接口所有方法的实现。不过,我们想要让它非常简单并且仅仅提供实现其中一些方法,比如解析url的功能。在Request初始化时初始化成员变量inputStream,并且用parseUrl()方法创建了一个字节数组来读入输入流,并转化为成一个StringBuffer对象,进而解析url。

技术分享 View Code

     Response类则提供了发送静态资源的功能。sendStaticResource()方法根据request内解析过的url,在本地寻找指定文件。如果找得到,把文件内容读出到浏览器,如果找不到,那么返回404的错误码。

2.3 PrimitiveServlet类    

技术分享 View Code

    PrimitiveServlet实现了标准的Servlet接口。我们简单的实现了Servlet生命周期的其他方法,并在service()方法我们做了最简单的向浏览器吐文字的操作。

2.4 ServletProcessor 和 StaticResourceProcessor

技术分享 View Code

    ServletProcessor是处理serlvet请求的类。它的作用在于,根据请求的路径实例化对应的Servlet,并且执行该Servlet的service()方法。

技术分享 View Code

  StaticResourceProcessor则简单的调用response的sendStaticResource()方法来返回静态资源。

    最后我们还需要建一个辅助类Constants指定静态资源的存放路径

技术分享 View Code

 3 启动服务器

    启动main函数来启动我们的http服务器。在浏览器输入http://localhost:8080/test,得到的结果如图3.1

       技术分享

 

                                               图3.1

这个url访问的是我的电脑中的一个文件test,它的存储路径为 /Users/wangyu/Documents/workspace/Tomcat/webroot/test,即当前项目的webroot目录下。

我们还可以输入一个servlet地址查看效果。在浏览器输入http://localhost:8080/v2/PrimitiveServlet,得到的结果如图3.2

       技术分享 

                           图3.2  

     这和我们的PrimitiveServlet的输出是一致的。

4 结语

    当然,tomcat的功能比我们的简易http服务器强大的多。但是通过这个最简单的http服务器,是否让你对http服务器有更深的一点了解了呢?


理解tomcat之搭建简易http服务器

标签:request   service   冰山一角   服务器   工作原理   

原文地址:http://zhanglida66.blog.51cto.com/12834458/1918626

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!