设为首页 收藏本站
查看: 486|回复: 0

[经验分享] Tomcat源码学习记录--web服务器初步认识

[复制链接]

尚未签到

发表于 2015-8-9 09:18:07 | 显示全部楼层 |阅读模式
  Tomcat作为开源的轻量级WEB服务器,虽然不是很适合某些大型项目,但是它开源,读其源代码可以很好的提高我们的编程功底和设计思维。Tomcat中用到了很多比较好的设计模式,其中代码风格也很值得我们去效仿。前阵子看了Tomcat源码分析这本书,特此过来分享分享自己的学习过程记录。说得不好,大神不要喷我。
  也不废话了,直入主题上代码。Tomcat是什么,Tomcat是一个web服务器,能够接收请求,作出响应。接收请求,作出响应让我们联想到Socket编程。我们可以起一个线程服务ServerSocket来监听本机的8080端口(可配置),然后就可以在浏览器上访问http://localhost:8080/index.html,这个时候就可以通过socket的inputstream获取到浏览器封装的HTTP请求了,然后就可以针对这个请求来大做文章。以下是服务端的代码



1 package cn.tim.server.core;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.io.OutputStream;
7 import java.net.InetAddress;
8 import java.net.ServerSocket;
9 import java.net.Socket;
10
11
12 /**
13  * HTTP服务器,主类
14  * @author TIM
15  *
16  */
17 public class HttpServer {
18     
19     
20     /**
21      * 端口
22      */
23     public int PORT = 8080;
24     
25     
26     /**
27      * 关闭指令
28      */
29     public final static String SHUTDOWN = "SHUTDOWN";
30     
31     
32     /**
33      * webroot根目录
34      */
35     public static final String WEB_ROOT =
36         System.getProperty("user.dir") + File.separator + "WebRoot";
37     
38     
39     public static void main(String[] args) {
40         
41         new HttpServer().await();
42         
43     }
44     
45     
46     /**
47      * 线程监听
48      */
49     private void await() {
50         
51         ServerSocket server = null;
52         try {
53             server = new ServerSocket(PORT,1,
54                     InetAddress.getByName("127.0.0.1"));
55         } catch (Exception e) {
56             e.printStackTrace();
57         }
58         
59         boolean shutdown = false;
60         while(!shutdown) {
61             Socket client = null;
62             InputStream in = null;
63             OutputStream out = null;
64             try {
65                 // 获取到请求socket
66                 client = server.accept();
67                 in = client.getInputStream();
68                 out = client.getOutputStream();
69                 
70                 // 生成request同时解析请求
71                 Request request = new Request(in);
72                 request.parse();
73                 
74                 // 生成response
75                 Response response = new Response(out);
76                 response.setRequest(request);
77                 // 根据资源定位符发送对应资源
78                 response.sendStaticResource();
79                 client.close();
80                 
81                 shutdown = request.getUri().equals(SHUTDOWN);
82             } catch (IOException e) {
83                 // TODO Auto-generated catch block
84                 e.printStackTrace();
85                 continue;
86             }
87            
88         }
89         
90     }
91     
92 }
  既然服务端HttpServer都出来了,Request都干些什么,request顾名思义,请求肯定是封装请求的一个JAVA类,肯定要能够解析HTTP请求,例如访问静态资源,就得获取到静态资源的资源定位符uri。
  HTTP请求Request类:



1 GET /index.html HTTP/1.1
2 Accept: text/html, application/xhtml+xml, */*
3 Accept-Language: zh-CN
4 User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0; MALCJS)
5 Accept-Encoding: gzip, deflate
6 Host: localhost:8080
7 DNT: 1
8 Connection: Keep-Alive
9 Cookie: principal=user:admin__password:admin


1 package cn.tim.server.core;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5
6 /**
7  * 封装请求
8  * @author TIM
9  *
10  */
11 public class Request {
12     
13     
14     /**
15      * 请求输入流
16      */
17     private InputStream in;
18     
19     
20     /**
21      * 资源定位符
22      */
23     private String uri;
24     
25     
26     /**
27      * 初始化request,传入socket输入流
28      * @param in
29      */
30     public Request(InputStream in) {
31         this.in = in;
32     }
33
34     
35     /**
36      * 根据请求字符串解析请求
37      */
38     public void parse() {
39         
40         try {
41             byte[] bytes = new byte[2048];
42             int i = in.read(bytes);
43            
44             StringBuffer buffer = new StringBuffer(2048);
45             for(int j=0; jindex1) {
69                 return requestString.substring(index1+1, index2);
70             }
71         }
72         return null;
73     }
74     
75
76     public InputStream getIn() {
77         return in;
78     }
79     
80     
81     public String getUri() {
82         return uri;
83     }
84     
85 }
  获取到资源定位符,接下来就是根据资源定位符来作出相应,当然实际的Tomcat处理方式肯定是很复杂的,我们只模仿其中简单的方式,访问静态资源。
  Response类:



1 package cn.tim.server.core;
2
3 import java.io.File;
4 import java.io.FileInputStream;
5 import java.io.IOException;
6 import java.io.InputStream;
7 import java.io.OutputStream;
8
9 public class Response {
10     
11     
12     /**
13      * 输出
14      */
15     private OutputStream out;
16     
17     
18     /**
19      * 缓冲大小
20      */
21     public final static int BUFFER_SIZE = 2048;
22     
23     
24     /**
25      * 请求,根据请求作出对应的响应
26      */
27     private    Request request;
28     
29     
30     public Response(OutputStream out) {
31         this.out = out;
32     }
33
34     
35     /**
36      * 发送静态资源
37      */
38     public void sendStaticResource() {
39         
40         byte[] bytes = new byte[BUFFER_SIZE];
41         InputStream in = null;
42         try {
43             File file = new File(HttpServer.WEB_ROOT, request.getUri());
44             // 请求的资源存在
45             if(file.exists()) {
46                 in = new FileInputStream(file);
47                 int ch;
48                 if((ch=in.read(bytes, 0, BUFFER_SIZE))!=-1) {
49                     out.write(bytes, 0, ch);
50                 }
51             }
52             // 请求资源不存在报404
53             else {
54                 String errorMessage = "HTTP/1.1 404 File Not Found\r\n" +
55                   "Content-Type: text/html\r\n" +
56                   "Content-Length: 23\r\n" +
57                   "\r\n" +
58                   "File Not Found";
59                 out.write(errorMessage.getBytes());
60             }
61         } catch (Exception e) {
62             // TODO Auto-generated catch block
63             e.printStackTrace();
64         } finally {
65             if(in!=null)
66                 try {
67                     in.close();
68                 } catch (IOException e) {
69                     // TODO Auto-generated catch block
70                     e.printStackTrace();
71                 }
72         }
73         
74     }
75     
76     
77     public void setRequest(Request request) {
78         this.request = request;
79     }
80
81 }
  这样,一个简单的Web服务器就实现了,可以访问静态资源,直接在浏览器上访问,没有找到对应的资源还可以报404错误。今天就写到这里,继续努力。。。
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-96245-1-1.html 上篇帖子: Tomcat启动分析(我们为什么要配置CATALINA_HOME环境变量) 下篇帖子: myeclipse内置tomcat与外置tomcat,在启动项目时,产生了不同反应。未解决
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表