Tomcat是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,也是一个servlet容器的优秀解决方案(它还是一个满足 Servlet 规范的容器)
一、Tomcat 和我们的 Web 应用是什么关系
我们一般需要把 Web 应用打成 WAR 包部署到 Tomcat 中,在我们的 Web 应用中,我们要指明 URL 被哪个类的哪个方法所处理「不论是原始的 Servlet 开发,还是现在流行的 Spring MVC 都必须指明」。
由于我们的 Web 应用是运行在 Tomcat 中,那么显然,请求必定是先到达Tomcat 的。Tomcat 对于请求实际上会进行如下的处理。
1.1 提供Socket服务,监听客户端端口号
在客户/服务器通信模式中, 服务器端需要创建监听端口的 ServerSocket, ServerSocket 负责接收客户连接请求,先创建一个ServerSocket,例如:
ServerSocket serverSocket = null;
int port = 80;
try {
serverSocket = new ServerSocket(port, 1, InetAddress.getByName("127.0.0.1"));
}
catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
为了方便测试,我设置接听了localhost的80端口,socketServer能时刻待命,接收来自客户端的连接请求,socketServer的实现使用了连接池和线程池,不过具体的实现不在本文讨论范围,有需要的朋友可以自行研究.
1.2 接收到客户请求后serverSocket会返回一个socket实例,然后获取InputStream和OutPutStream
socket = serverSocket.accept();
input = socket.getInputStream();
output = socket.getOutputStream();
1.3 然后件inputStream流解析成request,当然这个request还是很原始的request,获取请求里面的uri,解析之后将request传入response
Request request = new Request(input);
request.parse();
Response response = new Response(output);
response.setRequest(request);
response.sendStaticResource();
socket.close();
1.4 request从流中读取信息,并在请求行中解析出请求的uri
如:GET index.html HTTP/1.1 ,uri就会被设置成index.html,在项目的根目录创建一个webroot的文件夹,创建一个index.html文件,uri和这个文件名要对应。
在response中,将读取本地的webroot文件夹的request的uri对应名字的文件,通过socket的outputStream发送给客户端:
public void sendStaticResource() throws IOException {
byte[] bytes = new byte[BUFFER_SIZE];
FileInputStream fis = null;
try {
File file = new File(HttpServer.WEB_ROOT, request.getUri());
if (file.exists()) {
fis = new FileInputStream(file);
int ch = fis.read(bytes, 0, BUFFER_SIZE);
while (ch!=-1) {
output.write(bytes, 0, ch);
ch = fis.read(bytes, 0, BUFFER_SIZE);
}
}
else {
// file not found
String errorMessage = "HTTP/1.1 404 File Not Found\r\n" +
"Content-Type: text/html\r\n" +
"Content-Length: 23\r\n" +
"\r\n" +
"<h1>File Not Found</h1>";
output.write(errorMessage.getBytes());
}
}
catch (Exception e) {
// thrown if cannot instantiate a File object
System.out.println(e.toString() );
}
finally {
if (fis!=null)
fis.close();
}
}
运行httpServer的main方法,然后打开浏览器,输入localhost/index.html
参考:从零开始写一个静态Tomcat(壹)