簡體   English   中英

從本地服務器上的瀏覽器解析HTTP請求:Java

[英]Parse an HTTP request from browser on local server : Java

我正在嘗試創建一個簡單的HTML服務器,它將從我的瀏覽器讀取請求,從請求中解析所請求的文件,然后將適當的HTML提供回瀏覽器。 我需要能夠處理多個請求,所以我目前有一個Server類充當另一個可運行類RequestHandler的父類。 每次在服務器上建立連接時,都會運行可運行類RequestHandler的新實例。

package server;

import java.io.IOException;
import java.net.ServerSocket;

public class Server {

    public static void main(String[] args){
        try{
            ServerSocket serverSocket = new ServerSocket(8000);

            for(;;){
                Object block = new Object();
                RequestHandler handler = new RequestHandler(block, serverSocket);
                handler.start();

                try{
                    synchronized(block){
                        System.out.println("Server thread paused...");
                        block.wait();
                        System.out.println("Server thread creating new RequestHandler...");
                    }
                }catch(InterruptedException e){
                    System.out.println("Can't be interrupted!");
                    e.printStackTrace();
                }
            }

        }catch(IOException e){
            System.out.println("IOException!");
            e.printStackTrace();
        }
    }
}

package server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class RequestHandler extends Thread {

    Object block;
    ServerSocket serverSocket;
    BufferedReader socketReader;
    PrintWriter socketWriter;

    public RequestHandler(Object block, ServerSocket serverSocket){
        this.block = block;
        this.serverSocket = serverSocket;
    }

    @Override
    public void run() {
        try{
            System.out.println("Waiting for request...");
            Socket clientSocket = serverSocket.accept();
            System.out.println("Connection made.");

            synchronized(block){
                System.out.print("Notifying server thread...");
                block.notify();
                System.out.println("...done");
            }

            socketReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));            
            socketWriter = new PrintWriter(clientSocket.getOutputStream(), true);

            String input;
            while((input = socketReader.readLine()) != null){
                System.out.println(input);
            }
        }catch(IOException e){
            System.out.println("IOException!");
            e.printStackTrace();
        }
    }

}

我遇到的問題是我不知道如何組合請求的所有行,以便我可以解析所請求的文件。 如果它只是不斷地等待請求輸入,我將永遠不會達到我可以解析整個請求的程度。 我怎么解決這個問題?

只有在客戶端和服務器之間的連接關閉后,您的while循環才會中斷。 由於客戶端在發送請求后正在等待相同的連接以獲得響應,因此連接將保持打開狀態,因此readline()將阻止。 在while循環中,您必須在每一行之后檢查您是否已到達請求數據的末尾。 對於GET請求,您必須在HTTP標頭后面查找空行。 對於POST請求,您必須解析查找<Content-Length:N>的傳入標頭。 然后處理剩余的標題尋找空白行(就像在GET情況下一樣)。 一旦找到空白,就必須讀取<N>個字節。 此時,您知道已經完成了處理請求數據的處理,並且應該突破讀取循環。

有關詳細信息,請閱讀HTTP規范。

第一行為您提供請求方法以及請求的路徑,以下行是請求標題,標題塊以空行結束。

也就是說,你正在重新發明輪子:你可以使用com.sun.net.httpserver.HttpServer

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM