读了两章的 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 ...
随机推荐
- Python破解js加密实例(有道在线翻译)
在爬虫爬取网站的时候,经常遇到一些反爬虫技术,比如: 加cookie,身份验证UserAgent 图形验证,还有很难破解的滑动验证 js签名验证,对传输数据进行加密处理 对于js加密经过加密传输的就是 ...
- vue笔记(一)
Vue的开发 一丶下载 # 中文下载地址: https://cn.vuejs.org/ # 使用方式: # 1. 单独使用 vue.min.js.文件 # 2. 结合node.js使用集成工具 二丶v ...
- react-custom-scrollbars的使用
react-custom-scrollbars的作用 流畅的本机浏览器滚动 移动设备的本机滚动条 完全可定制 自动隐藏 自动高度 通用(在客户端和服务器上运行) requestAnimationFra ...
- Google Analytics 学习笔记三 —— GA常用术语
一.Sessions 1.会话,指定的时间段内在网站上发生的一系列互动,例如一次会话可以是网页浏览.事件或电子商务等.参考Google Analytics(分析)如何定义网络会话 2.会话结束的方式分 ...
- 微软官方的.net系列文档
闲下来的时候给自己补充补充基础,微软官方的相关技术文档地址,最新最全最官方:https://docs.microsoft.com/zh-cn/ 其中.NET专区:https://docs.micros ...
- jar 冲突、class 冲突的检测脚本
思路很简单,解开war包,解开 jar 包,发现有同名 package.class 就报出来,不管是否“兼容” .. import zipfile import io from collections ...
- 9.InfluxDB-InfluxQL基础语法教程--LIMIT and SLIMIT 子句
本文翻译自官网,官网地址:(https://docs.influxdata.com/influxdb/v1.7/query_language/data_exploration/) LIMIT和SLIM ...
- 如何在Etherscan.io 部署ETH以太坊智能合约 如何在15分钟内创建你的加密货币
一.概述 ETH 网络这里就不介绍了,这篇文章主要记录在以太坊主网和测试网络部署一个智能合约,也就是如何发币. 二.部署合约需要的生产工具 准备工具前,建议大家准备个VPN,因为会访问国外网 ...
- Bert实战---情感分类
1.情感分析语料预处理 使用酒店评论语料,正面评论和负面评论各5000条,用BERT参数这么大的模型, 训练会产生严重过拟合,,泛化能力差的情况, 这也是我们下面需要解决的问题; 2.sigmoid二 ...
- 网络编程ssh,粘包
1.什么是socket? TCP,可靠地,面向连接协议,有阻塞rect udp,不可靠的,无线连接的服务 这里因为不需要阻塞,所以速度会很快,但安全性不高 2.关于客户端退出而服务器未退出的解决办法 ...