读了两章的 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 [email protected]
     * @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 [email protected]
     * @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 [email protected]
     * @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 [email protected]
     * @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 [email protected]
     * @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 [email protected]
     * @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开发工作.在这最后的几个月,我也将继续修炼内功.学习更多的招式.晚安!

原文地址:https://www.cnblogs.com/zumengjie/p/11553130.html

时间: 2024-07-29 14:15:39

读了两章的 How Tomcat Works的相关文章

how tomcat works 读书笔记四 tomcat的默认连接器

其实在第三章,就已经有了连接器的样子了,不过那只是一个学习工具,在这一章我们会开始分析tomcat4里面的默认连接器. 连接器 Tomcat连接器必须满足以下几个要求 1 实现org.apache.cataline.Connector接口 2 负责创建实现了org.apache.cataline.Request接口的request对象 3 负责创建实现了org.apache.cataline.Response接口的response对象 这里默认的连接器的原理很简单,就是等待http请求,创建re

How Tomcat Works 2

上一节(How Tomcat Works 1 编写一个简单静态web服务器)编写了一个简单的web服务器,只能处理静态的资源,本节将继续向前迈出一个小步,创建两个不同的servlet容器,能够利用servlet简单的处理动态内容.注意每节的代码都是基于上一节的继续丰富,因此有必要从第一节开始看起. 在编写代码之前,需要先大体了解一下Servlet是什么,方便后面的理解,下面就是一个最简单的Servlet什么也没做: package prymont; import java.io.IOExcept

《How Tomcat Works》读书笔记(二)

<How Tomcat Works>读书笔记(二) 这是<How Tomcat Works>第一二章的读书笔记.第一张主要写了一个静态资源处理的web服务器,第二章加了对servlet的处理. 1. 概述 1.1 架构 HttpServer:表示Http服务器,与客户端通信,处理Http请求. StaticResourceProcessor:对静态资源请求进行处理. ServletProcessor:对Servlet资源请求进行处理. Request:表示Http请求,实现了Ser

How Tomcat works — 四、tomcat启动(3)

上一节说到StandardService负责启动其子组件:container和connector,不过注意,是有先后顺序的,先启动container,再启动connector,这一节先来看看container. 目录 Pipeline和Vavle StandardEngine类和StandardHost类 StandardContext类 总结 Pipeline和Vavle 在第二节(How Tomcat works — 二.tomcat启动(1))中没有介绍关于Pipeline和Vavle,因

how tomcat works 总结 二

第五章 servlet容器 第 5 章讨论 container 模块.container 指的是 org.apache.catalina.Container 接口,有4 种类型的 container:engine, host, context 和 wrapper.这章提供了两个工作于 context 和wrapper 的程序. 容器共分四类,类图如下: 一个wrapper就是一个servlet; 一个context包含若干个wrapper; 本章分了两个部分,第一部分是wrapper,第二部分是

how tomcat works 读书笔记(二)----------一个简单的servlet容器

app1 (建议读者在看本章之前,先看how tomcat works 读书笔记(一)----------一个简单的web服务器 http://blog.csdn.net/dlf123321/article/details/39378157) 回顾我们上一章,我们开发了一个最最简单的web服务器,它可以使用户访问服务器内的静态资源.当然这是远远不够的,在这一节里,我们就试着让服务器在能相应静态资源的基础上继续支持servlet. servlet接口 javax.servlet.Servlet接口

How Tomcat Works - Connector

在前两章实现的WebServer还有很多问题,比如: 1)最后一个out.print("xxx")没有生效. 2)没有解析请求头,请求方法,协议,uri等,而这些内容在servlet里面是可能要用到的. 在这一章中,增加了一个新的servlet:ModerServlet: import java.io.IOException; import java.io.PrintWriter; import java.util.Enumeration; import javax.servlet.S

how tomcat works

目标 深入剖析tomcat •Java Web 服务性能优化实践2014-11-04阅读225 •How Tomcat work之第十五章之Digester之setting property2014-07-30阅读253 •How Tomcat work 之第十四章之server and services 之application2014-07-29阅读194 •how tomcat work之第十四章:server and service2014-07-27阅读352 •How Tomcat

阅读《大型网站技术架构》前两章心得体会及总结

最近阅读了<大型网站技术架构>这一本书,对于这一行业刚入门的菜鸟来说,虽然只读了前两章,却让我感受颇深,同时也学习和见识到了很多之前不了解.不明白的东西. 通过阅读前两章,我才真正的初步明白了一个刚刚成型的小型网站是如何一步一步的成长为一个大型网站.从网站的最开始的基础架构,到一步步实现网站的性能提升,到如何处理网站的高并发数据,到使用反响代理和CDN加速网站响应,让我一步一步的真正的认识到了架构的重要性,也让我这个菜鸟学习到了很多之前不懂的知识. 第一章主要讲授了大型网站架构演化的发展历程,