• Tomcat源码学习(14)How Tomcat works(转)


    启动应用程序

        你可以从ex03.pyrmont.startup.Bootstrap类来启动应用程序。这个类在Listing 3.1中给出。
             Listing 3.1: Bootstrap类
    package ex03.pyrmont.startup;
    import ex03.pyrmont.connector.http.HttpConnector;
    public final class Bootstrap {
         public static void main(String[] args) {
             HttpConnector connector = new HttpConnector();
             connector.start();
         }
    }
        Bootstrap类中的main方法实例化HttpConnector类并调用它的start方法。HttpConnector类在Listing 3.2给出。
             Listing 3.2: HttpConnector类的start方法
    package ex03.pyrmont.connector.http;
    import java.io.IOException;
    import java.net.InetAddress;
    import java.net.ServerSocket;
    import java.net.Socket;
    public class HttpConnector implements Runnable {
         boolean stopped;
         private String scheme = "http";
         public String getScheme() {
             return scheme;
         }
         public void run() {
             ServerSocket serverSocket = null;
             int port = 8080;
             try {
                 serverSocket = new
                 ServerSocket(port, 1, InetAddress.getByName("127.0.0.1"));
             }
             catch (IOException e) {
                 e.printStackTrace();
                 System.exit(1);
             }
             while (!stopped) {
                 // Accept the next incoming connection from the server socket
                 Socket socket = null;
                 try {
                     socket = serverSocket.accept();
                }
                 catch (Exception e) {
                     continue;
                 }
                 // Hand this socket off to an HttpProcessor
                 HttpProcessor processor = new HttpProcessor(this);
                 processor.process(socket);
             }
         }
         public void start() {
             Thread thread = new Thread(this);
             thread.start ();
         }
    }

    连接器

        ex03.pyrmont.connector.http.HttpConnector类指代一个连接器,职责是创建一个服务器套接字用来等待前来的HTTP请求。这个类在Listing 3.2中出现。
        HttpConnector类实现了java.lang.Runnable,所以它能被它自己的线程专用。当你启动应用程序,一个HttpConnector的实例被创建,并且它的run方法被执行。
        注意: 你可以通过读"Working with Threads"这篇文章来提醒你自己怎样创建Java线程。
        run方法包括一个while循环,用来做下面的事情:
    • 等待HTTP请求
    • 为每个请求创建个HttpProcessor实例
    • 调用HttpProcessor的process方法
         注意:run方法类似于第2章中HttpServer1类的await方法。
        马上你就会看到HttpConnector类和ex02.pyrmont.HttpServer1类非常相像,除了从 java.net.ServerSocket类的accept方法中获得一个套接字之后,一个HttpProcessor实例会被创建,并且通过传递该套 接字给它的process方法调用。
        注意:HttpConnector类有另一个方法叫getScheme,用来返回一个scheme(HTTP)。
        HttpProcessor类的process方法接受前来的HTTP请求的套接字,会做下面的事情:
    1. 创建一个HttpRequest对象。
    2. 创建一个HttpResponse对象。
    3. 解析HTTP请求的第一行和头部,并放到HttpRequest对象。
    4. 解析HttpRequest和HttpResponse对象到一个ServletProcessor或者 StaticResourceProcessor。像第2章里边说的,ServletProcessor调用被请求的servlet的service方 法,而StaticResourceProcessor发送一个静态资源的内容。
        process方法在Listing 3.3给出.
    Listing 3.3: HttpProcessor类process方法
    public void process(Socket socket) {
         SocketInputStream input = null;
         OutputStream output = null;
         try {
             input = new SocketInputStream(socket.getInputStream(), 2048);
             output = socket.getOutputStream();
             // create HttpRequest object and parse
             request = new HttpRequest(input);
             // create HttpResponse object
             response = new HttpResponse(output);
             response.setRequest(request);
             response.setHeader("Server", "Pyrmont Servlet Container");
             parseRequest(input, output);
             parseHeaders(input);
             //check if this is a request for a servlet or a static resource
             //a request for a servlet begins with "/servlet/"
             if (request.getRequestURI().startsWith("/servlet/")) {
                 ServletProcessor processor = new ServletProcessor();
                 processor.process(request, response);
             }
             else {
                 StaticResourceProcessor processor = new
                 StaticResourceProcessor();
                 processor.process(request, response);
             }
             // Close the socket
             socket.close();
             // no shutdown for this application
         }
         catch (Exception e) {
             e.printStackTrace ();
         }
    }
        process首先获得套接字的输入流和输出流。请注意,在这个方法中,我们适合继承了java.io.InputStream的SocketInputStream类。
    SocketInputStream input = null;
    OutputStream output = null;
    try {
         input = new SocketInputStream(socket.getInputStream(), 2048);
         output = socket.getOutputStream();
        然后,它创建一个HttpRequest实例和一个 instance and an HttpResponse instance and assigns
    the HttpRequest to the HttpResponse.
    // create HttpRequest object and parse
    request = new HttpRequest(input);
    // create HttpResponse object
    response = new HttpResponse(output);
    response.setRequest(request);
        本章应用程序的HttpResponse类要比第2章中的Response类复杂得多。举例来说,你可以通过调用他的setHeader方法来发送头部到一个客户端。
    response.setHeader("Server", "Pyrmont Servlet Container");
        接下去,process方法调用HttpProcessor类中的两个私有方法来解析请求。
    parseRequest(input, output);
    parseHeaders (input);
        然后,它根据请求URI的形式把HttpRequest和HttpResponse对象传给ServletProcessor或者StaticResourceProcessor进行处理。
    if (request.getRequestURI().startsWith("/servlet/")) {
         ServletProcessor processor = new ServletProcessor();
         processor.process(request, response);
    }
    else {
         StaticResourceProcessor processor =
             new StaticResourceProcessor();
         processor.process(request, response);
    }
        最后,它关闭套接字。
    socket.close();
        也要注意的是,HttpProcessor类使用org.apache.catalina.util.StringManager类来发送错误信息:
    protected StringManager sm =
         StringManager.getManager("ex03.pyrmont.connector.http");
        HttpProcessor类中的私有方法--parseRequest,parseHeaders和normalize,是用来帮助填充HttpRequest的。这些方法将会在下节"创建一个HttpRequest对象"中进行讨论。
  • 相关阅读:
    CentOS7安装MySql5.7
    环境变量配置
    Spring 注解
    MySQL
    常用命令
    Android Studio & IntelliJ IDEA常见问题与设置
    order by、group by、having的区别
    把WebStrom添加到右键菜单
    解决github访问速度慢的问题
    docker修改时区
  • 原文地址:https://www.cnblogs.com/macula7/p/1960783.html
Copyright © 2020-2023  润新知