採坑-深入剖析Tomcat一書

採坑一、第一章 一個簡單的web服務器 

整體沒碰到什麼問題,按書寫就可以了,但,最後一步卡死了,那個鬱悶呀。覈對了幾遍都沒錯。最後才解決。

項目結構:

環境

jdk1.8,IDEA 。

需要自己額外引入這兩個jar。

直接上代碼先

HttpServer.java

package com.diy.tomcat.server;


import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class HttpServer {

    /**
     *  WEB_ROOT是HTML和其他文件所在的目錄。對於這個包,WEB_ROOT是工作目錄下的“webroot”目錄。工作目錄是文件系統中調用java命令的位置。
     */
    public static final String WEB_ROOT = System.getProperty("user.dir") + File.separator + "webroot";

    // 關機提示
    private static final String SHUTDOWN_COMMEND = "/SHUTDOWN";

    // 收到關機命令
    private boolean shutdown = false;

    public static void main(String[] args) {
        HttpServer httpServer = new HttpServer();
        httpServer.await();
    }

    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 inputStream = null;
            OutputStream outputStream = null;

            try {
                socket = serverSocket.accept();
                inputStream = socket.getInputStream();
                outputStream = socket.getOutputStream();
                // 創建請求對象並且解析
                Request request = new Request(inputStream);
                request.parse();

                // 創建返回對象
                Response response = new Response(outputStream);
                response.setRequest(request);
                response.sendStaticResource();

                // 關閉socket
                socket.close();

                // 檢查前面的URI是否是關閉命令
                shutdown = request.getUri().equals(SHUTDOWN_COMMEND);

            } catch (Exception e) {
                e.printStackTrace();
                continue;
            }

        }


    }

}

Request.java

package com.diy.tomcat.server;

import java.io.IOException;
import java.io.InputStream;

public class Request {
    private InputStream inputStream;
    private String uri;

    public Request(InputStream inputStream) {
        this.inputStream = inputStream;
    }

    /**
     * 解析HTTP請求中的原始數據.
     */
    public void parse() {
        StringBuffer stringBuffer = new StringBuffer(2048);
        int i;
        byte[] buffer = new byte[2048];
        try {
            i = inputStream.read(buffer);
        } catch (IOException e) {
            e.printStackTrace();
            i = -1;
        }
        for (int j = 0; j < i; j++) {
            stringBuffer.append((char) buffer[j]);
        }
        System.out.println(stringBuffer.toString());
        uri = parseUri(stringBuffer.toString());
    }

    /**
     * 解析HTTP請求的URI.
     */
    private String parseUri(String requestString) {
        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;
    }

    public String getUri() {
        return uri;
    }

}

Response.java

package com.diy.tomcat.server;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;

public class Response {

    private static final int BUFFER_SIZE = 1024;
    Request request;
    OutputStream outputStream;

    public Response(OutputStream outputStream) {
        this.outputStream = outputStream;
    }

    public void setRequest(Request request) {
        this.request = request;
    }


    public void sendStaticResource() throws IOException {
        byte[] bytes = new byte[BUFFER_SIZE];
        FileInputStream fileInputStream = null;
        try {
            File file = new File(HttpServer.WEB_ROOT, request.getUri());
            if (file.exists()) {
                fileInputStream  = new FileInputStream(file);
                int ch = fileInputStream.read(bytes, 0, BUFFER_SIZE);
                StringBuffer sb = new StringBuffer();
                //響應頭信息
                sb.append("HTTP/1.1 200 OK\n");
                sb.append("Content-Type: text/html;charset=UTF-8\n");
                sb.append("\r\n");
                while (ch != -1) {
                    sb.append(new String(bytes));
                    outputStream.write(sb.toString().getBytes());
                    ch = fileInputStream.read(bytes, 0, BUFFER_SIZE);
//                    outputStream.write(bytes, 0, ch);
                }
            } 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>";
                outputStream.write(errorMessage.getBytes());
            }
        } catch (Exception e) {
            e.printStackTrace();
            // 如果不能實例化文件對象,則拋出
            System.out.println(e.toString());
        } finally {
            if (fileInputStream != null) {
                fileInputStream.close();
                outputStream.flush();
                outputStream.close();
            }
        }
    }

}

我碰到的坑在Response 裏面。當按照書中說的寫完之後,找不到文件可以返回,但把index文件放入指定的目錄中後。

原文代碼:

結果。

代碼

對比發現區別在

這一部分。慢慢調試,最終

改爲這樣,沒有這一行會一直循環

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章