zoukankan      html  css  js  c++  java
  • 读了两章的 How Tomcat Works

    周一发现了一本书.How Tomcat Works 惯例先到豆瓣搜书评.结果书评出奇的好.然后下载了PDF.从简介中看,本书的每个章节都会不断的围绕怎么建造一个Tomcat讲解.我本人比较喜欢这种造轮子的书.原因很简单,比较笨.如果书中没有代码,很难从脑海中构件代码结构.可是万万没想到,看到第三章,就发现,书中的代码不全,完整的代码还要到GitHub下载.无奈只能放下这本好书.(个人觉得看书就是要了解本质,如果书中的源码不全,而是给出片段,剩下的还要到项目中找,我觉得你还不如让我去直接看Tomcat的源码.实名DISS,因为这件事昨晚都没睡好.)不过开卷有益,贴出来两段代码,安慰下自己.

    本次代码都有注释,就不一一介绍了.

    public class HttpServer {
        //C:workspaceyourTomcatsrc   /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
    
    ".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
    " +
                            "Content-Type:text/html
    " +
                            "Content-Length: 23
    " +
                            "
    " +
                            "<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开发工作.在这最后的几个月,我也将继续修炼内功.学习更多的招式.晚安!

  • 相关阅读:
    vue开发常用技巧总结(一)
    js时间戳转固定日期格式输出处理
    vue恢复初始数据
    Feature Police导致iframe页面无法使用粘贴功能
    页面异步请求canceled 或 network中接口请求成功但无法查看返回值
    我在阿里云做云开发平台
    Python项目中的requirements文件
    Json常用格式
    浅谈开机启动_windows
    mmdetection 报错: AttributeError: ‘ConfigDict‘ object has no attribute ‘pipeline‘
  • 原文地址:https://www.cnblogs.com/zumengjie/p/11553130.html
Copyright © 2011-2022 走看看