下面代码参考《how tomcat works》 一书中的源码。源码可以从我的GIT上下载:https://github.com/gpqhl0071/howTomcatWorks.git
跟着代码,了解Connector
- 入口方法
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();
}
}
- 方法实现Runnable 接口
- 创建socket服务端
- 通过26行到37行代码,处理用户请求
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 class HttpProcessor
源码分析:
- 38行public void process(Socket socket)入口方法
- 46行、49行,分别创建对象HttpRequest、HttpResponse
- 54行,parseRequest方法解析生成request对象,仔细查看parseRequest
- 139行,input.readRequestLine(requestLine);,通过程序自定义的SocketInputStream完成对象的封装。最终将对象封装到HttpRequestLine。然后生成HttpRequest,本质上就是生成HttpServletRequest对象,提供给用户使用。
- 55行,parseHeaders方法解析生成header对象,91行代码同上面一样,通过SocketInputStream类将数据封装到HttpHeader中,与上面同理,生成HttpServletRequest请求头的对象属性信息。
- 执行61行或64行将用户的请求交给service方法,这里通过ServletProcessor类完成的service方法调用。下面讲解具体代码逻辑。
- 至此请求便流转到了用户的servlet方法上了(doget、dopost…)
public class ServletProcessor
源码:
https://github.com/gpqhl0071/howTomcatWorks/blob/master/src/ex03/pyrmont/ServletProcessor.java
源码分析:
- 18行process方法的入参,HttpRequest,HttpResponse。是我们在HttpProcessor中封装的对象。
- 22行到41行,将我们的请求url进行加工处理,并在项目中找到URL所指向的我们定义的servlet类。
- 47行到48行,将HttpRequest,HttpResponse使用外观设计模式,对其进行封装,避免用户直接操作HttpRequest,HttpResponse造成安全隐患。
- 49行代码,执行servlet.service(requestFacade, responseFacade);
上面根据书中第三章连接器,整理流程完毕。
总结几点:
1、连接器Connector就是将servlet服务挂起。
2、处理用户提交的servlet请求,将请求送转到service方法,并且封装好HttpServletRequest,HttpServletResponse