不正確的伺服器響應_靜態資源伺服器的簡單實現
阿新 • • 發佈:2020-12-15
技術標籤:不正確的伺服器響應
Server類 1.Server類作用 讀取伺服器配置 建立伺服器傾聽Socket,並在每次接收到請求後將請求交由一個新的HttpHandler執行緒進行處理 2.讀取伺服器配置 在靜態程式碼塊讀取伺服器配置,包括伺服器傾聽埠、資源根路徑、錯誤頁面路徑、預設頁面路徑2.接收請求並移交HttpHandler處理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");}
HttpHandler類 1.HttpHandler類作用 處理到達伺服器的請求,響應資源給客戶端 由於是靜態資源伺服器,所以需要獲取資源的路徑(注意解決中文路徑的亂碼問題) 為了瀏覽器按正確格式解析資源,所以要獲取資源的ContentType 2.獲取請求資源的路徑 通過Socket的輸入流獲取請求行,在請求行中獲取請求資源的路徑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(); }}
3.獲取請求資源的ContentType 通過MimetypesFileTypeMap物件的getContentType方法獲取請求資源的ContentType/** * 獲取請求資源的路徑 * 用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;}
/** * 獲取請求資源的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(); }}