读了两章的 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 ...
随机推荐
- C#通过PInvoke调用c++函数的备忘录
目前知道的情况被调用的C/C++函数只能是全局函数 不能调用类中的成员方法 被调用的C函数必须使用extern “C“包含,保证采用的导出函数名生成规则和.NET一致 函数调用约定通常使用WINAPI ...
- SQLMap常用教程
先安装 python环境(2.6.x或2.7版本) ,再将SQLMap 放在安装目录下 注意:sqlmap只是用来检测和利用sql注入点的,并不能扫描出网站有哪些漏洞,使用前请先使用扫描工具扫出sql ...
- React组件安装使用和生命周期函数
React安装在使用react时 需要安装 两个模块 react react-dom 初始化时 需要用到react-dom中的render方法 具体如下: import ReactDOM from & ...
- Unity导出Gradle工程给Android Studio使用
1 Unity导出Gradle项目 Unity打包时Build System选择Gradle,勾选Export Project 2 Android Studio导入Unity导出的Gradle项目 打 ...
- Linux 信号量之Posix基于内存的信号量
信号量(semaphore),也和互斥锁一样提供了线程间或者进程间的同步功能. 信号量有三种: Posix有名字的信号量 Posix基于内存的信号量 System V信号量 信号量比互斥锁高级,互斥锁 ...
- 以太网PHY寄存器分析【转】
转自:https://blog.csdn.net/Firefly_cjd/article/details/79825869 以太网PHY寄存器分析 1 1.以太网PHY标准寄存器分析 2 ...
- 五、select的5种子句
1.Where 条件查询 比较运算符: 运算符 说明 > < = >= <= !=或<> In 在某集合内 between 在某范围内 In ...
- python爬虫(5)——BeautifulSoup & docker基础
BeautifulSoup基础实战 安装:pip install beautifulsoup4 常用指令: from bs4 import BeautifulSoup as bs import url ...
- LR性能测试分析流程
LR性能测试分析流程 一. 判断测试结果的有效性 (1)在整个测试场景的执行过程中,测试环境是否正常. (2)测试场景的设置是否正确.合理. (3)测试结果是否直接暴露出系统的一些问题. (4 ...
- docker学习12-docker快速搭建禅道环境
前言 bug管理系统是每个公司测试团队必备的,当去一个新的公司组建一个测试团队的时候,需快读搭建一套bug管理系统,使用docker搭建禅道就非常方便. 拉取镜像 先拉取zentao镜像,镜像地址ht ...