《深入剖析tomcat》读书笔记1

前言:

有比较宏观的问题,如下(持续更新中):

1.能否用一句话说明tomcat或者一个java web服务器做的事情?

2.http请求是怎么进入tomcat服务器的,即内部的调用序列是怎么样的?

3.tomcat或者jboss如何和我们的web框架整合?

……

也有微观的问题,如下(持续更新中):

1.http1.1的新特性是什么?你又是否知道为什么会新添加这些新特性?

2. servlet实现了的singleTreadModel接口,就是线程安全的吗?

3.你也许知道filter是干嘛的,但是你知道filter是在哪里、何时、被哪个模块调用执行的吗?

……

深入剖析tomcat读书笔记1涉及1-3章,本身并不涉及tomcat的任何源码。

第一章-----一个简单的web服务器

    介绍了简单的实现web服务器的方法(对于静态资源的处理,不涉及动态内容)。解析http报文得到请求的对象,处理请求对象得到结果,封装结果返回相应对象。其实都是在用Java来实现一些字符串操作,通过字节流来承载内容。

Http协议

    主要简单介绍了http协议,更详细地介绍在

http://www.cnblogs.com/li0803/archive/2008/11/03/1324746.html

http请求组成:请求行、请求头、实体。

请求行:请求方法----URI----协议/版本

请求头:Accept、Accept-Charset、Host、User-Agent、Content-Length、Content-Type

实体:各个请求参数

http响应组成:状态行、响应报头、响应正文

状态行:协议—状态码—描述

响应报头:Location、Server、Content-Length、Content-Type、Last-Modified

Socket类

    Socket就是网络连接的端点,有Socket和serverSocket两种,前者为客户端建立,后者为服务端建立。客户端和服务端建立了socket链接,就可以进行通信。

socket通信是什么?

    我认为本质上就是一边输入数据,一边输出数据。在java里面,就是用封装的字节流来处理。

如何通信?

    发送数据方调用socket的getOutPutStream()方法,获取OutputStream对象,用该OutputStream对象创建一个PrintWriter对象,调用PrintWriter的print()方法即可。接受数据方调用socket的getInputStream()方法,获取InputStream对象,用该InputStream创建一个BufferReader,调用BufferReader的read()方法即可。

serverSocket

    serverSocket是服务端创建的,要等待来自客户端的请求。当serverSocket接收到了连接请求后,它会创建一个socket处理与客户端的通信。就是调用serverSocket.accept()方法。

serverSocket构造函数中有一个backlog属性,表示连接的队列的长度(而不是连接的数量)。“输入连接指示(对连接的请求)的最大队列长度被设置为 backlog 参数。如果队列满时收到连接指示,则拒绝该连接。”

 

第二章-----一个简单的servlet容器

   servlet容器主要可以处理动态内容。和Servlet技术并行的技术是cgi。和一个在腾讯工作的同学交流,腾讯web系统采用得就是cgi技术,后台用C来实现。

Servlet是一套规范,要熟悉他,要参考在javax.servlet和java.servlet.http两个包下的接口和类。最重要的接口就是servlet接口,有5个方法。

public void init(ServletConfig config)throws ServletException;
//当某个servlet被实例化后,servlet容器调用其init()方法进行初始化,比如设置数据库链接、初始化默认值等等
public ServletConfig getServletConfig();
//取得的是web.xml文件中,<servlet><init-param>配置的参数
public void service(ServletRequestreq, ServletResponse res) throws ServletException,
IOException;
//当servlet的一个客户端请求到达后,servlet容器就调用相应servlet的service()方法。参数类型分别为ServletRequest和ServletResponse。前者包含http请求的信息,后者封装servlet的响应信息。
public String getServletInfo();
//用Servlet类的getServletInfo方法获取网页的说明信息,GetServletInfo()方法是一个可选的方法,它提供有关servlet的信息,如作者、版本、版权。
public void destroy();
//在将servlet实例从服务中移出前,servlet容器会调用servlet实例的destory()方法。调用该方法,一般用来清理自身持有的资源,如内存、文件句柄和线程等等。

   如何实现一个简单的servlet容器?

  作者给出了一个实例。思路如下:

1:等待HTTP请求。

2:构造一个ServletRequest对象和一个ServletResponse对象。

3:假如该请求需要一个静态资源的话,调用StaticResourceProcessor实例的process方法,同时传递ServletRequest和ServletResponse对象。

4:假如该请求需要一个servlet的话,加载servlet类并调用servlet的service方法,同时传递ServletRequest和ServletResponse对象

5: 处理后结果,把封装为ServletResponse,返回。


第三章—连接器

     tomcat使用的servlet容器的名字是catalina,主要包含2个模块:连接器(connector)和容器(container)。

连接器

    连接器作用:解析http请求头(其实不只是可以接受http协议,还可以接受AJP协议,用于纯web服务器比如apache和应用服务器比如tomcat的连接。关于web服务器和应用服务器的区别,可以自行谷歌之),使得servlet实例能够获取到请求头、cookie等信息。

一个简单的连接器实现

一个简单的连接器由2个部分组成:httpConnector、httpProcessor。

httpConnector作用:

1.      等待http请求

2.      为每个请求创建一个httpProcessor实例

3.      调用httpProcessor的process()方法

核心的代码如下:

while (!stopped) {
      // Acceptthe next incoming connection from the server socket
      Socket socket = null;
      try {
        socket = serverSocket.accept();
      }
      catch (Exception e) {
        continue;
      }
      // Handthis socket off to an HttpProcessor
      HttpProcessor processor = new HttpProcessor(this);
      processor.process(socket);
    }

      httpProcessor作用:创建请求对象和响应对象。显然,为了servlet能够处理,请求对象必须实现httpRequest接口,响应对象必须实现httpResponse接口。

     对于每一个传入的http请求,完成4个操作:

1.  创建一个HttpRequest对象;

2.  创建一个HttpResponse对象;

3.  解析Http的请求行和请求头,填充HttpRequest对象;

4.  将HttpRequest和HttpResponse传递给servlet的service()方法。

解析http请求步骤如下:

1.  读取套接字的输入流;

2.  解析请求行;

3.  解析请求头;

4.  解析cookie;

5.  获取参数

读取套接字的输入流仅需要调用servlet的getInputStream();解析请求行、请求头、cookie

的parse方法都是按照http协议,比如如何从

“GET /my/app/servlet?username=mohe&password=123 HTTP /1.1”字符串中得到请求方法、URI、版本version。这些都是纯字符串操作,大量运用了indexof()、subString()等方法。

猜你喜欢

转载自blog.csdn.net/randyjiawenjie/article/details/8656667