标签:http协议 servlet tomcat 源码 读书笔记
另外,StringManager的产生是单例模式,大家可以看看源码
我们这一章的servlet代码如下
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
public class ModernServlet extends HttpServlet {
  public void init(ServletConfig config) {
    System.out.println("ModernServlet -- init");
  }
  public void doGet(HttpServletRequest request, 
    HttpServletResponse response) 
    throws ServletException, IOException {
    
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    out.println("<html>");
    out.println("<head>");
    out.println("<title>Modern Servlet</title>");
    out.println("</head>");
    out.println("<body>");
    out.println("<h2>Headers</h2");
    Enumeration headers = request.getHeaderNames();
    while (headers.hasMoreElements()) {
      String header = (String) headers.nextElement();
      out.println("<br>" + header + " : " + request.getHeader(header));
    }
    //省略部分request信息
    out.println("</body>");
    out.println("</html>");
  }
}
系统提炼出来了一个Bootstrap类,加载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();
  }
}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();
    }
  }
input = new SocketInputStream(socket.getInputStream(), 2048);
SocketInputStream是一个实现了InputStream接口的包装类,我们之所以用SocketInputStream,就是为了用它的readRequestLine()方法readHeader方法。前者能读出request请求的请求方法,uri和请求协议,后者能读出请求头。
    parseRequest(input, output);
    parseHeaders(input);
这两个方法是process方法的核心,也可以说是整个第三章的核心。往简单的说,这两个方法干的事就是解析http请求填充HttpRequst对象,当然这里面有很多很多细节的东西。
这部分说简单很简单,说麻烦也巨麻烦,大体来说就是五个部分
1读取套接字的输入流
 就是下面这行代码
  input = new SocketInputStream(socket.getInputStream(), 2048);
 大家有兴趣可以看看readRequestLine的源代码,不过不必深究。
2解析请求行(就是 http请求的第一行 包括请求方法 uri 协议版本)
3解析请求头
4解析Cookie
5获取参数(就是前文提到的lazy load)
  public PrintWriter getWriter() throws IOException {
    // autoflush is true, println() will flush,
    // but print() will not.
    writer = new PrintWriter(output, true);
    return writer;
  }public PrintWriter getWriter() throws IOException {
    ResponseStream newStream = new ResponseStream(this);       // this 指代HttpResopnse
    newStream.setCommit(false);
    OutputStreamWriter osr =       
      new OutputStreamWriter(newStream, getCharacterEncoding());
    writer = new ResponseWriter(osr);
    return writer;
  }
How Tomcat Works读书笔记三-------连接器
标签:http协议 servlet tomcat 源码 读书笔记
原文地址:http://blog.csdn.net/dlf123321/article/details/40180563