1. 程式人生 > 其它 >不正確的伺服器響應_靜態資源伺服器的簡單實現

不正確的伺服器響應_靜態資源伺服器的簡單實現

技術標籤:不正確的伺服器響應

Server類

16c568ce8464f5af80b2e9bb1b901c65.png

1.Server類作用 讀取伺服器配置 建立伺服器傾聽Socket,並在每次接收到請求後將請求交由一個新的HttpHandler執行緒進行處理 2.讀取伺服器配置 在靜態程式碼塊讀取伺服器配置,包括伺服器傾聽埠、資源根路徑、錯誤頁面路徑、預設頁面路徑
static {    InputStream serverConfigStream = Server.class.getClassLoader().getResourceAsStream("server-config.properties");    Properties serverConfigProps = new Properties();    try {        serverConfigProps.load(serverConfigStream);    } catch (IOException e) {        throw new RuntimeException("server-config not found");    }    //伺服器傾聽埠    serverPort = Integer.parseInt(serverConfigProps.getProperty("server-port"));    //資源根路徑    resourceRoot = serverConfigProps.getProperty("resource-root");    //錯誤頁面路徑    errorPage = serverConfigProps.getProperty("error-page");    //預設頁面路徑    defaultPage = serverConfigProps.getProperty("default-page");}
2.接收請求並移交HttpHandler處理
public static void main(String[] args) {    try {        ServerSocket serverSocket = new ServerSocket(serverPort);        while (true) {            Socket socket = serverSocket.accept();            new Thread(new HttpHandler(socket)).start();        }    } catch (IOException e) {        e.printStackTrace();    }}
HttpHandler類

16c568ce8464f5af80b2e9bb1b901c65.png

1.HttpHandler類作用 處理到達伺服器的請求,響應資源給客戶端 由於是靜態資源伺服器,所以需要獲取資源的路徑(注意解決中文路徑的亂碼問題) 為了瀏覽器按正確格式解析資源,所以要獲取資源的ContentType 2.獲取請求資源的路徑 通過Socket的輸入流獲取請求行,在請求行中獲取請求資源的路徑
/** * 獲取請求資源的路徑 * 用URLDecoder的decode方法給路徑解碼防止中文亂碼 * * @return */public String getRequestPath() {    BufferedReader br = new BufferedReader(new InputStreamReader(is));    try {        //請求行        String requestLine = br.readLine();        String[] split = requestLine.split("\\s");        if (split.length == 3) {            //用URLDecoder的decode方法給路徑解碼防止中文亂碼            return URLDecoder.decode(split[1], "utf-8");        }    } catch (IOException e) {        e.printStackTrace();    }    return null;}
3.獲取請求資源的ContentType 通過MimetypesFileTypeMap物件的getContentType方法獲取請求資源的ContentType
/** * 獲取請求資源的ContentType * * @param file * @return */private String getContentType(File file) {    return mimetypesFileTypeMap.getContentType(file);}
4.響應請求的資源給客戶端 請求路徑未攜帶請求資源路徑,則響應預設頁面 請求資源不存在,則響應錯誤頁面 請求資源存在,則獲取資原始檔輸入流以及資原始檔的ContentType並響應給客戶端
/** * 響應請求的資源給客戶端 */private void response(String path) {    //響應請求資源給客戶端的輸出流    BufferedOutputStream bos;    //獲取請求資源的輸入流    BufferedInputStream bis;    try {        //請求的資原始檔        File file = new File(Server.resourceRoot + path);        bos = new BufferedOutputStream(os);        String separator = File.separator;        if (!path.equals("/")) {//請求路徑中含資源路徑            if (file.exists()) {//檔案存在                //響應頭                bos.write("HTTP/1.1 200 ok\r\n".getBytes());                bos.write(("Content-Type:" + getContentType(file) + "\r\n").getBytes());                bos.write(("Content-Length:" + file.length() + "\r\n").getBytes());                //必須寫入空行,否則瀏覽器不解析                bos.write("\r\n".getBytes());                System.out.println("一個客戶端建立連線");            } else {//檔案不存在                //響應頭                bos.write("HTTP/1.1 404 file not found\r\n".getBytes());                bos.write("Content-Type:text/html\r\n".getBytes());                //必須寫入空行,否則瀏覽器不解析                bos.write("\r\n".getBytes());                System.out.println("一個客戶端建立連線");                //檔案找不到,就用錯誤頁面代替                file = new File(Server.resourceRoot + Server.errorPage);            }        } else {//請求路徑中不含資源路徑,則直接跳轉到預設頁面            //響應頭            bos.write("HTTP/1.1 200 ok\r\n".getBytes());            bos.write("Content-Type:text/html\r\n".getBytes());            //必須寫入空行,否則瀏覽器不解析            bos.write("\r\n".getBytes());            System.out.println("一個客戶端建立連線");            file = new File(Server.resourceRoot + Server.defaultPage);        }        //響應體        bis = new BufferedInputStream(new FileInputStream(file));        byte[] buffer = new byte[1024];        int length;        while ((length = bis.read(buffer)) != -1) {            bos.write(buffer, 0, length);        }        bos.flush();    } catch (IOException e) {        e.printStackTrace();    }}