一.连接器

    1. 什么是连接器?

    所谓连接器就是负责创建一个服务器套接字实例,并根据该实例等待客户端的请求,然后提供HttpServlerRequestHttpServletResponse实例。

    在接下的代码中,这个连接器将会解析HTTP请求头,使servlet实例能够获取请求头,cookie、和请求参数/值等信息。

  2.错误信息类

    对于Tomcat中出现的错误信息也需要进行配置和说明,就好比如说javasrc中也有相应的错误信息处理的类

    Tomcat错误信息类放在StringManager类中。例如,对于系统管理员根据Tomcat的错误日志消息定位到发生异常的位置。对于servlet程序员来说,在抛出的每个javax.servlet.servletException异常中,Tomcat都会发送一条特殊的错误消息。

    Tomcat处理错误消息的方法是将错误消息存在分布在不同包的中properties文件中,便于读取和编辑。

    当包中的某个类需要在其保内的properties文件中查找错误消息时,它会先获取对应的StringManager实例。若对于每一个类需要查找错误消息都要实例化一个StringManager实例,显然开销是很大。基于节约成本的思想,StringManager类被设置成单例类,即其中的构造方法是私有的,仅能调用getManager()方法获取StringManger类的实例,并且其传递的参数是包名。

    比如《深入剖析Tomcat》书中ex03.pyrmont.connector.http包下,含有3properties文件,StringManager实例会根据运行该程序的服务器语言环境选择使用何种语言的properties文件.

        Servlet(二)--连接器这是StringManager的构造函数,是私有的。

    Servlet(二)--连接器这是StringManager类的getManager()的方法,用于获取StringManager实例。

    Servlet(二)--连接器通过传递包名获取StringManger实例

    Servlet(二)--连接器调用StringManager类的getString()方法,向其传递错误信息

    Servlet(二)--连接器查看properties文件中相关字串,可以得知“httpProcessor.parseHeaders.colon”错误将产生“Invalid HTTP header format”错误消息提示。

二.使用连接器的Servlet程序

    现在开始介绍使用连接器的Servlet程序,本程序分为三个模块。

    1.启动模块.启动模块只有一个类(Bootstrap.java),这个类负责启动程序。

    2.连接器模块.连接器模块可以分成5个部分

       连接器及其支持类(HttpConnector.javaHttpProcessor.java

        表示HTTP请求的类(HttpRequest.java)及其支持类(HttpHeader.javaHttpRequestLine.java

        表示HTTP响应的类(HttpResponse.java)及其支持类()

        外观类(HttpRequestFacade.javaHttpResponseFacade.java

        资源类(Constants.java

    3.核心模块.核心模块包括两个类,servletProcessor类和StaticResourceProcessor

    1. Servlet程序将使用一下包名,类名

        l ex03.pyrmont.connector

            Ø RequestStream.java

            Ø ResponseStream.java

            Ø ResponseWriter.java

        l ex03.pyrmont.connector.http

            Ø HttpConnector.java--连接器类

            Ø HttpProcessor.java--连接器支持类

            Ø HttpRequest.java--解析请求类

            Ø HttpRequestFacade.java--解析请求类的外观类

            Ø HttpResponse.java--响应类

            Ø HttpResponseFacade.java--响应类的外观类

            Ø Constants.java--资源类

            Ø SocketInputStream.java--套接字输入流类

            Ø HttpHeader.java--解析请求头类

            Ø HttpRequestLine.java--解析请求行类

        l ex03.pyrmont.startup

            Ø Bootstrap.java--启动类

        l ex03.pyrmont

            Ø ServletProcessor.java

            Ø StaticResourceProcessor.java

        l org.apache.catalina.util

            Ø StringManager.java

            Ø RequestUtil.java

            Ø ParameterMap.java

        2. UML类图


        3. 启动模块

            Servlet(二)--连接器

            本程序通过Bootstrap类作为启动类,通过实例化HttpConnector对象,在调用其start()方法启动整个服务器程序。

        4. 连接器模块

            连接器模块是整个程序最为复杂的模块,在上一个Servlet程序中,HttpServer类负责等待HTTP请求,并创建RequestResponse对象。在这个程序改变思路,通过使用连接器来等待HTTP请求,即通过HttpConnector类等待HTTP请求,创建RequestResponse对象工作由HttpProcessor类。

          在接下的程序中,不同于上一个Servlet程序,HTTP请求对象使用HttpRequest类表示,HttpRequest类实现了javax.servlet.http.HttpServletRequest接口。HTTP响应对象使用HttpResponse类表示,HttpResponse类实现了java.servlet.http.HttpSeveltResponse接口。

            HttpRequest对象会转型为HttpServletRequest对象,然后作为参数传递给service()方法。使用连接器时不知道并调用的servlet会使用诸如:“URI”,“查询字符串”,“参数”,“Cookie”,“其他一些请求头信息”的值。因此每个HttpRequest对象必须正确获取和设置以上的值。

            HttpResponse对象会转型为HttpServletResponse对象,该类会向浏览器输出字节流,通过使用PrintWriter对象。

        本Servlet程序的连接器将使用SocketInputStream类,该类继承自InputStream类,从输入流读取字节流。SocketInputStream类是InputStream类的包装类,可以通过调用套接字的getInputStream()方法获取实例。这个类有两个重要的方法,其一是readRequestLine()方法,读取HTTP请求的第一行内容,该内容包括,请求方法,URI,和HTTP协议版信息,返回的是HttpRequestLine的是实例。其二是readHeader()方法,使用该方法将返回HTTP请求信息的一对名字/值信息,并返回HttpHeader实例。注意,使用readRequestLine()方法应该注意,必须在readHeader()方法前使用。因为,套接字的输入流处理字节流是从第1个字节读取到最后一个字节(并不能从后往前读),因此必须使用readRequestLine()方法。


            1. HttpConnector--连接器类。实现了Runnable接口





























相关文章: