0

如何使用这样的系统解析 URL 查询。

例如,在变量中获取这些 URL 参数。

http://localhost?format=json&apikey=838439873473kjdhfkhdf

http://tutorials.jenkov.com/java-multithreaded-servers/multithreaded-server.html

我制作了这些文件

WorkerRunnable.java

package servers;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.net.Socket;

/**

*/
public class WorkerRunnable implements Runnable{

protected Socket clientSocket = null;
protected String serverText   = null;

public WorkerRunnable(Socket clientSocket, String serverText) {
    this.clientSocket = clientSocket;
    this.serverText   = serverText;
}

public void run() {
    try {
        InputStream input  = clientSocket.getInputStream();
        OutputStream output = clientSocket.getOutputStream();
        long time = System.currentTimeMillis();
        output.write(("HTTP/1.1 200 OK\n\nWorkerRunnable: " +
                this.serverText + " - " +
                time +
                "").getBytes());
        output.close();
        input.close();
        System.out.println("Request processed: " + time);
    } catch (IOException e) {
        //report exception somewhere.
        e.printStackTrace();
    }
  }
 }

多线程服务器.java

package servers;

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

public class MultiThreadedServer implements Runnable{

protected int          serverPort   = 8080;
protected ServerSocket serverSocket = null;
protected boolean      isStopped    = false;
protected Thread       runningThread= null;

public MultiThreadedServer(int port){
    this.serverPort = port;
}

public void run(){
    synchronized(this){
        this.runningThread = Thread.currentThread();
    }
    openServerSocket();
    while(! isStopped()){
        Socket clientSocket = null;
        try {
            clientSocket = this.serverSocket.accept();
        } catch (IOException e) {
            if(isStopped()) {
                System.out.println("Server Stopped.") ;
                return;
            }
            throw new RuntimeException(
                "Error accepting client connection", e);
        }
        new Thread(
            new WorkerRunnable(
                clientSocket, "Multithreaded Server")
        ).start();
    }
    System.out.println("Server Stopped.") ;
}


private synchronized boolean isStopped() {
    return this.isStopped;
}

public synchronized void stop(){
    this.isStopped = true;
    try {
        this.serverSocket.close();
    } catch (IOException e) {
        throw new RuntimeException("Error closing server", e);
    }
}

private void openServerSocket() {
    try {
        this.serverSocket = new ServerSocket(this.serverPort);
    } catch (IOException e) {
        throw new RuntimeException("Cannot open port 8080", e);
    }
}

}

调度.java

 package servers;

 public class Dispatch {

/**
 * @param args
 */
public static void main(String[] args) {
    MultiThreadedServer server = new MultiThreadedServer(9000);
    new Thread(server).start();

    try {
        Thread.sleep(20 * 1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("Stopping Server");
    server.stop();

}

}
4

3 回答 3

2

到目前为止你做得很好。

一次从 InputStream 中读取数据(BufferedReader 可能会有所帮助)。阅读并学习 HTTP 协议(​​请参阅此处的请求消息部分:http ://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol )。

客户端发送的第一行将遵循该格式:GET /foo.html?x=y&a=b HTTP/1.1后跟 \n\n 即方法、URL(带有查询参数)和协议。拆分该行(在空格上...),然后根据规范分解 URL。

您需要的一切都可以在用于解析数据的 String 类中找到。

于 2012-04-04T02:38:13.633 回答
0

您忘记阅读客户发送的内容。在 http 中,客户端打开连接,然后发送请求并等待服务器回复。

要阅读请求,您有两个选择。使用 BufferedReader 或逐字节读取。BufferedReader 更容易。您为每一行获得一个字符串,并且可以轻松地将其拆分或替换字符或其他任何内容;)

读取每个字节的速度要快一些,但只有在您需要每秒处理大量请求时才有意义。比这真的可以有所作为。我只是把这些信息告诉你;)

我已经在您的 WorkerRunnable.java 中包含了阅读所需的部分。这会读取并打印出整个客户端请求。

启动服务器,打开浏览器并输入:http://127.0.0.1:9000/hello?one=1&two=2&three=3 控制台上的第一行将显示:GET /hello?one=1&two=2&three=3 HTTP /1.1

在关闭 OutputStream 之前,请务必调用 flush() 方法。这将强制写出任何缓冲的字节。如果您不这样做,则可能会丢失一些字节/字符,并且您可能会花费很长时间来寻找错误。

try {
    InputStream input  = clientSocket.getInputStream();

    // Reading line by line with a BufferedReader
    java.io.BufferedReader in = new java.io.BufferedReader(
        new java.io.InputStreamReader(input));
    String line;
    while ( !(line=in.readLine()).equals("") ){
        System.out.println(line);
    }

    OutputStream output = clientSocket.getOutputStream();
    long time = System.currentTimeMillis();
    output.write(("HTTP/1.1 200 OK\n\nWorkerRunnable: " +
            this.serverText + " - " +
            time +
            "").getBytes());
    output.flush();
    //Flushes this output stream and forces any buffered output bytes to be written out.
    output.close();
    input.close();
    System.out.println("Request processed: " + time);

我不知道你在那里做什么。您刚刚告诉我们您需要解析 URL,但也许更好的方法是使用 simpleframework (http://www.simpleframework.org) 它就像一个嵌入式 HTTP-Server,您可以查看教程。它将为您提供一个请求对象,您可以从那里轻松获取 url 中的参数。

于 2012-04-04T04:10:26.063 回答
-2

从技术上讲,你可以,但它会让你自己实现 http 协议。

更好的选择是使用 Oracle 的 Java Http Server。有关提示,请参阅以下文章http://alistairisrael.wordpress.com/2009/09/02/functional-http-testing-with-sun-java-6-httpserver/

于 2012-04-04T02:05:46.667 回答