读了两章的 How Tomcat Works
周一发现了一本书.How Tomcat Works 惯例先到豆瓣搜书评.结果书评出奇的好.然后下载了PDF.从简介中看,本书的每个章节都会不断的围绕怎么建造一个Tomcat讲解.我本人比较喜欢这种造轮子的书.原因很简单,比较笨.如果书中没有代码,很难从脑海中构件代码结构.可是万万没想到,看到第三章,就发现,书中的代码不全,完整的代码还要到GitHub下载.无奈只能放下这本好书.(个人觉得看书就是要了解本质,如果书中的源码不全,而是给出片段,剩下的还要到项目中找,我觉得你还不如让我去直接看Tomcat的源码.实名DISS,因为这件事昨晚都没睡好.)不过开卷有益,贴出来两段代码,安慰下自己.
本次代码都有注释,就不一一介绍了.
public class HttpServer {
//C:\workspace\yourTomcat\src /webroot
public static final String WEB_ROOT = System.getProperty("user.dir")+ File.separator+ "webroot"; //停止语句
private static final String SHUTDOWN_COMMAND="/SHUTDOWN";
//停止标识符
private boolean shutdown = false; /*
* @author 顶风少年
* @date 2019/9/16 16:57
* @mail dfsn199703132038@foxmail.com
* @throws
* @param
* @result void
* @notify 监听请求
* version 1.0
*/ 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 request = new Request(input);
request.parse();
//创建相应对象
Response response = new Response(output);
response.setRequest(request);
response.sendStaticResource();
//关闭socket通道
socket.close();
//如果客户端传递的停止则,更改监听标记
shutdown = request.getUri().equals(SHUTDOWN_COMMAND);
}catch (Exception e){
e.printStackTrace();
continue;
} }
}
}
public class Request {
private InputStream input;
private String uri; public Request(InputStream input) {
this.input = input;
} /*
* @author 顶风少年
* @date 2019/9/16 16:57
* @mail dfsn199703132038@foxmail.com
* @throws
* @param
* @result void
* @notify 解析请求内容
* version 1.0
*/
public void parse() {
//将字节转换成字符
StringBuffer request = new StringBuffer(2048);
//是否读取结束
int i;
//将字节读取到此处
byte[] buffer = new byte[2048];
try {
//读取
i = input.read(buffer);
} catch (IOException e) {
e.printStackTrace();
i = -1;
}
//循环将字节放到String中
for (int j = 0; j < i; j++) {
request.append((char) buffer[j]);
}
//解析请求资源路径
uri = parseUri(request.toString());
} /*
* @author 顶风少年
* @date 2019/9/16 16:59
* @mail dfsn199703132038@foxmail.com
* @throws
* @param
* @param requestString
* @result java.lang.String
* @notify 解析请求资源路径
* version 1.0
*/
private String parseUri(String requestString) {
//记录前两个空格,第一个空格和第二个空格之间是 请求路径 GET /SHUTDOWN HTTP/1.1
int index1, index2;
//找到第一个空格的位置
index1 = requestString.indexOf(" ");
if (index1 != -1) {
//找到第二个空格的位置
index2 = requestString.indexOf(" ", index1 + 1);
if (index2 > index1) {
//截取请求路径
return requestString.substring(index1 + 1, index2);
}
}
return null;
} /*
* @author 顶风少年
* @date 2019/9/16 17:00
* @mail dfsn199703132038@foxmail.com
* @throws
* @param
* @result java.lang.String
* @notify 获取请求路径
* version 1.0
*/
public String getUri() {
return uri;
}
}
public class Response {
private static final int BUFFER_SIZE = 1024;
Request request;
OutputStream output; public Response(OutputStream output) {
this.output = output;
} /*
* @author 顶风少年
* @date 2019/9/16 17:01
* @mail dfsn199703132038@foxmail.com
* @throws
* @param
* @param request
* @result void
* @notify 设置request
* version 1.0
*/
public void setRequest(Request request) {
this.request = request;
} /*
* @author 顶风少年
* @date 2019/9/16 17:02
* @mail dfsn199703132038@foxmail.com
* @throws
* @param
* @result void
* @notify 相应资源
* version 1.0
*/
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);
//如果读取到了内容
output.write("HTTP/1.1 200 OK\\r\\nContent-Type: text/html\r\n\r\n".getBytes());
while (ch != -1) {
//将内容写入到响应体
output.write(bytes, 0, ch);
//再次读取
ch = fis.read(bytes, 0, BUFFER_SIZE);
}
} else {
//每一找到请求资源
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) {
e.printStackTrace();
} finally {
//关闭流
if (fis != null) {
fis.close();
}
}
}
}
说起来这是我加入博客园一来,第一次写带感情的文章.从16年6月认识java.到18年工作做得微信小程序,以及少量的java工作.再到今年的运维,偏向java.这几年,我一直不断的学习java.java基础的书看了三本.
其他的语言js,html,c++,c#包括sql.这么多语言来讲,我还是最喜欢java,起先写java就是写demo,工作后的一段时间写crud觉得十分无趣.在后来读了几本书,才知道原来在crud的工作中,也可以加入设计模式,编
程思想.以后的工作,我时常将一些模式,和一些设计写到工作中的crud代码中,力图让工作不在那么无趣,也让自己写的代码看上去优雅些.对于java只想说,不忘初心,方得始终.
最后希望明年我能找到一份真正的java开发工作.在这最后的几个月,我也将继续修炼内功.学习更多的招式.晚安!
读了两章的 How Tomcat Works的更多相关文章
- How tomcat works(深入剖析tomcat)阅读笔记1-4章
How tomcat works chapter 1 简单的web服务器 这一张的主要内容就是实现一个简单的静态资源服务器,socket编程,利用java提供的socket和serverSocket编 ...
- 深入刨析tomcat 之---第8篇 how tomcat works 第11章 11.9应用程序,自定义Filter,及注册
writed by 张艳涛, 标签:全网独一份, 自定义一个Filter 起因:在学习深入刨析tomcat的学习中,第11章,说了调用过滤链的原理,但没有给出实例来,自己经过分析,给出来了一个Filt ...
- how tomcat works 札记(两)----------一个简单的servlet集装箱
app1 (看着眼前这章建议读者,看how tomcat works 札记(一个)----------一个简单的webserver http://blog.csdn.net/dlf123321/art ...
- 深入刨析tomcat 之---第11篇 how tomcat works( 第15章 ) 如何解析web.xml 文件
writedby 张艳涛 记得当年是学习jsp的时候,写过web.xml中的标签.在之后的springmvc中也是有关于配置mvc 过滤器 和dispatchServlet的标签,之前是看不懂呢!看到 ...
- How tomcat works(深入剖析tomcat)servlet容器
How tomcat works (5)servlet容器阅读笔记 第四章阅读了tomcat默认连接器的实现,当时connector中的使用的容器是自定义的容器,也是非常之简单奥,一个人就干完了所有的 ...
- How Tomcat Works(十八)
在前面的文章中,如果我们要启动tomcat容器,我们需要使用Bootstrap类来实例化连接器.servlet容器.Wrapper实例和其他组件,然后调用各个对象的set方法将它们关联起来:这种配置应 ...
- how tomcat works 读书笔记四 tomcat的默认连接器
事实上在第三章,就已经有了连接器的样子了,只是那仅仅是一个学习工具,在这一章我们会開始分析tomcat4里面的默认连接器. 连接器 Tomcat连接器必须满足下面几个要求 1 实现org.apache ...
- how tomcat works 总结
希望各位网友在看完<<how tomcat works>>一书或者鄙人的tomcat专栏文章后再看这篇博客 这里主要是梳理各个章节的核心概念 第一章 一个简单的Web服务器 第 ...
- How tomcat works(深入剖析tomcat)(7) Logger
How tomcat works (7)日志记录器 总体概述 顾名思义,这一章将的是tomcat的日志记录器组件,比较简单,tomcat提供了几种类型不同的日志记录器,但是所有的日志记录器都需要实现L ...
随机推荐
- charles注册码及中文版本,支持window和mac
安装证书: 安装完证书之后设置代理 2个* ,代表全部 注册码: Registered Name: https://zhile.io License Key: 48891cf209c6d32bf4 破 ...
- SAP MM 公司间STO里外向交货单与内向交货单里序列号对应关系
SAP MM 公司间STO里外向交货单与内向交货单里序列号对应关系 笔者所在的A项目,后勤模块里有启用HU管理,序列号管理,批次管理等功能,以实现各个业务场景下的追溯. 公司间转储订单流程里,如果是整 ...
- Scrum冲刺第四篇
一.每日例会 会议照片 成员 昨日已完成的工作 今日计划完成的工作 工作中遇到的困难 陈嘉欣 撰写博客,管理成员提交代码 和队友一同开发音乐控制模块 对音频控制方面知识了解少,功能实现困难 邓镇港 帮 ...
- 【已采纳】supervisor在服务器端(linux),如何一直运行你的python代码
正式开始之前,说一下我的项目是放在虚拟环境里的,具体什么是虚拟环境,怎么创建,请自行百度噢! 一.安装 源码安装 先下载最新的supervisor安装包:https://pypi.python.o ...
- Jmeter吞吐量控制器
吞吐量控制器 场景: 假如有两个业务分别是A, B在同一线程组内有10并发, 7个做A业务, 3个做B业务,吞吐量控制器比较推荐使用. 添加吞吐量控制器 用法1: Percent Executio ...
- 获取List<object>中对象的属性值
List<object> ls = new List<object>(); ls.Add(,name="sqm"}); ls.Add(,name=" ...
- [MySQL] 事务的ACID特性
事务的ACID特性: 原子性(atomicity):一个事务是一个不可分割的最小工作单位,事务中的所有操作要么都做,要么都不做. 一致性(consistency):事务前后数据的完整性必须保持一致.事 ...
- 其他综合-CentOS 7 搭建模板机
CentOS 7 搭建模板机 [基于此文章的环境]点我快速打开文章 1.修改静态地址 ip a|awk -F '[ /]+' '$NF~/eth0/ {print $3}' cat >/etc/ ...
- 【我的第一个现实漏洞分析】 CVE-2017-17215 华为智能路由器HG532 漏洞分析笔记
0x00 基本信息 2017.11.27 Check Point团队报告华为 HG532 产品的远程命令执行漏洞(CVE-2017-17215),Mirai的升级版变种中已经使用该漏洞. 华为HG53 ...
- 软件工程1916|W(福州大学)_助教博客】团队第六次作业(第9次)成绩公示
1. 作业链接: 团队作业第六次-团队Github实战训练 2. 评分准则: 本次作业评分分为两部分,一部分是博客分数(满分100分),另一部分是工程能力分数(满分30分). 博客分数计算方式: 团队 ...