博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Tomcat源码学习记录--web服务器初步认识
阅读量:4562 次
发布时间:2019-06-08

本文共 6395 字,大约阅读时间需要 21 分钟。

  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 TIM15  *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                 // 获取到请求socket66                 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                 // 生成response75                 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 block84                 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.12 Accept: text/html, application/xhtml+xml, */*3 Accept-Language: zh-CN4 User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0; MALCJS)5 Accept-Encoding: gzip, deflate6 Host: localhost:80807 DNT: 18 Connection: Keep-Alive9 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 in29      */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; j
index1) {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             // 请求资源不存在报40453             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 block63 e.printStackTrace();64 } finally {65 if(in!=null)66 try {67 in.close();68 } catch (IOException e) {69 // TODO Auto-generated catch block70 e.printStackTrace();71 }72 }73 74 }75 76 77 public void setRequest(Request request) {78 this.request = request;79 }80 81 }

  这样,一个简单的Web服务器就实现了,可以访问静态资源,直接在浏览器上访问,没有找到对应的资源还可以报404错误。今天就写到这里,继续努力。。。

  

转载于:https://www.cnblogs.com/TimBing/p/3627872.html

你可能感兴趣的文章
[转载]求职者防骗必读!楼主亲身经历告诉你岗前培训多么不靠谱而且违法!
查看>>
Hibernate内存溢出分析一例
查看>>
基于Axis1.4的webservice接口开发(接口调用)
查看>>
Hive内置函数详解
查看>>
【转】MyEclipse快捷键大全
查看>>
IT职业技能图谱10--Hadoop家族技能图谱
查看>>
Java - 反射(1)
查看>>
控制台中显示执行的Sql语句
查看>>
Linux(Centos7)下搭建SVN服务器
查看>>
安卓开发的Tasks and Back Stack
查看>>
Ansi,UTF8,Unicode编码
查看>>
原子变量的性能问题
查看>>
Sybase PowerDesigner 15.0 完美版+特别文件
查看>>
快速傅立叶之二
查看>>
cetos 6.3 安装 apache+mysql+php
查看>>
js编写简单的贪吃蛇游戏
查看>>
2018/12/01 一个64位操作系统的实现 第四章 导入kernel.bin(4)
查看>>
如何在windows xp professional安装iis的解决方法
查看>>
抽象类和接口
查看>>
使用ASP.NET Atlas AutoComplete Behavior或AutoComplete Extender实现自动完成功能(下)
查看>>