本文为《how tomcat works》的学习笔记与自己对于tomcat服务器的理解心得。如有任何错误,欢迎指正。
**我在理解服务器的结构时将服务器的类分为两类:一:处理类,二:工具类**。
一:**处理类**,tomcat的本质是socket网络编程,通过获取socket来获得读取流和输出流,从而获取浏览器发送的信息,并且根据获取的信息返回浏览器请求的结果。而处理类负责持有,传递socket或是socket的封装request和response,实现信息的接收,处理以及资源的返回。例如Connector,Processor,Container,pipeline,servlet等等。
二:**工具类**,工具类则是帮助处理类进行参数解析,参数判断,方法封装,日志记录,亦或是获取所需资源的类,如request,response,logger,lorder等等。
在接下来的博文中,我会使用这两个名词对服务器组成类进行归类和划分。
**tomcat服务器基本原型**
事实上,tomcat的核心使用的是socket的编程,利用serversocket类的accept()方法获取socket,从socket之中取出inputstream和outputstream,利用inputstream读取客户端发送过来的请求,根据请求的内容利用outputstream向客户端发送回复的内容。下面是一个最简单的服务器雏形,他通过await()方法独立完成了对socket的解析,并返回所需的内容
public class HttpServer {
//服务器内容的存储目录,在这里获取所需的资源
public static final String WEB_ROOT =
System.getProperty("user.dir") + File.separator + "webroot";
// 关闭循环的字符串命令
private static final String SHUTDOWN_COMMAND = "/SHUTDOWN";
// 服务器的状态,为true时停止循环结束服务器的运行
private boolean shutdown = false;
public static void main(String[] args) {
HttpServer server = new HttpServer();
server.await();
}
//处理请求的方法
public void await() {
//建立服务器
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 (!shutdown) {
Socket socket = null;
InputStream input = null;
OutputStream output = null;
try {
socket = serverSocket.accept();
input = socket.getInputStream();
output = socket.getOutputStream();
//这里新建了request类,对于inputstream进行了封装,request有许多参数字段,通过parse方法读取inputstream进行填充
Request request = new Request(input);
request.parse();
// 这里新建了response,对于outputstream进行了封装
Response response = new Response(output);
response.setRequest(request);
//如果是servlet开头,则交给ServletProcessor1进行处理,其中可能会涉及到对参数的判定,如果不是,则交给StaticResoureProcessor直接获取指定名称的资源进行返回。
if (request.getUri().startsWith("/servlet/")) {
ServletProcessor1 processor = new ServletProcessor1();
processor.process(request, response);
}
else {
StaticResoureProcessor processor =
new StaticResourceProcessor();
processor.process(request, response);
}
// 关闭socket
socket.close();
//如果uri里面包换关闭指令的字符串,则停止循环,关闭服务器
shutdown = request.getUri().equals(SHUTDOWN_COMMAND);
}
catch (Exception e) {
e.printStackTrace();
continue;
}
}
}
}
一个服务器雏形涉及到三个处理类,httpserver,servletprocessor,staticresourceprocessor,完成了三个任务:一 接收socket,二 将socket里面的内容封装进request和response方面后面的类进行调用,三 根据socket里面的内容交给其他类进行处理。httpserver负责了前两个任务,而servletprocessor和staticresourceprocessor则负责第三个任务。
这里暂时略过request的parse()方法,主要介绍一下http协议的格式与内容,具体的解析方法可以看<how tomcat work>的第三章
## http协议 ##
Http协议主要可以划分为3块,第一块是requestline,第二块是header,第三块是请求正文
requestline由三部分组成,method,uri+参数,协议版本
POST /examples/default.jsp HTTP/1.1
method可以是get或者是post,如果get的话,那么参数会跟随在uri的后面以?+键值对的形式,最后是协议版本。如果浏览器禁用cookie的话,sessionid也会跟在uri后面
headers包含了客户端的信息以及对请求主体内容的重要信息,如context-length,浏览器的设置语言等,以键值对(name:value)的形式表现,结尾以CRLF隔开不同的键值对。其中cookie也被包含在header里面,如果value的值不只一个的话,用;表示多个值。
Accept: text/plain; text/html
Accept-Language: en-gb
Connection: Keep-Alive
Host: localhost
User-Agent: Mozilla/4.0 (compatible; MSIE 4.01; Windows 98)
Content-Length: 33
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
最后则是用户自己的请求内容。如果是get的话则其为空。
tomcat学习笔记
最新推荐文章于 2022-05-30 13:33:23 发布