读了两章的 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# 随机 抽奖 50个随机码 不重复
static List<int> Given50RandomNumbers() { List<int> intList = new List<int>(); for ...
- Winform中对xml文件进行保存时空白节点自动换行问题的解决
场景 Winform中自定义xml配置文件后对节点进行读取与写入: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/10053213 ...
- SQL 除去数字中多于的0
/* 除掉多于的0 */ CREATE FUNCTION [dbo].[fn_ClearZero] ( ) ) ) AS BEGIN ); IF (@inValue = '') SET @return ...
- python 跟踪IP模块
#coding=utf-8 import re import subprocess def tracertIP(ip): p = subprocess.Popen(['tracert',ip],std ...
- Java生鲜电商平台-一次代码重构的实战案例
Java生鲜电商平台-一次代码重构的实战案例 说明,Java开源生鲜电商平台-一次代码重构的实战案例,根据实际的例子,分析出重构与抽象,使代码更加的健壮与高效. 1.业务说明 系统原先已有登录功能,我 ...
- git报错 - remote: HTTP Basic: Access denied
十年河东,十年河西,莫欺少年穷 学无止境,精益求精 git 拉取代码报: remote: HTTP Basic: Access denied,这是因为你的GIT密码修改后,需要重新认证授权,那么怎么操 ...
- SAP 如何得到交货单上的序列号清单?
SAP 如何得到交货单上的序列号清单? 以内向交货单为例(外向交货单方法了类似)予以说明. 1)VL33N,在交货单显示界面, 但是没办法通过这个界面里导出序列号清单. 2),只能通过查表的方式导出序 ...
- 在使用 Fortify进行源码扫描时需要做对项目需要做什么?
1.一般我们的项目都是svn 或git 进行管理的,为了扫出异常的问题 做好把 “” .svn “” 文件删除 2.把我们的项目需要的jar 文件放到一个文件夹内同项目一起进行扫描.这样为 ...
- js 加密混淆工具
访问路径:https://www.sojson.com/javascriptobfuscator.html
- MES助力日立电梯提升精细化管理水平
项目背景介绍 日立电梯在2008年到2012年期间分别在五地工厂(上海.广州.天津.成都.扶梯)上线了ERP系统,在后续的使用时间里,逐渐发现现有ERP系统对于生产现场管理,产品质量追溯,产能控制等方 ...