标签: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