从本地服务器上的浏览器解析HTTP请求:Java

时间:2011-10-19 20:48:01

标签: java http request response

我正在尝试创建一个简单的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();
        }
    }

}

我遇到的问题是我不确定如何组合请求的所有行,以便我可以解析所请求的文件。如果它只是不断地等待请求输入,我将永远不会达到我可以解析整个请求的程度。我该如何解决这个问题?

2 个答案:

答案 0 :(得分:3)

只有在客户端和服务器之间的连接关闭后,您的while循环才会中断。由于客户端在发送请求后正在等待相同的连接以获得响应,因此连接将保持打开状态,因此readline()将阻止。在while循环中,您必须在每一行之后检查您是否已到达请求数据的末尾。对于GET请求,您必须在HTTP标头后面查找空行。对于POST请求,您必须解析查找< Content-Length:N>的传入标头。然后处理剩余的标题寻找空白行(就像在GET情况下一样)。找到空白之后,你必须阅读< N>字节。此时,您知道已经完成了处理请求数据的处理,并且应该突破读取循环。

阅读HTTP规范以获取详细信息。

答案 1 :(得分:1)

第一行为您提供请求方法以及请求的路径,以下行是请求标题,标题块以空行结束。

那就是说,你正在重新发明轮子:你可以使用com.sun.net.httpserver.HttpServer