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();
    }
  }
 }

MultiThreadedServer.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);
    }
}

}

Dispatch.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

あなたは今のところ元気です。

一度に 1 行ずつ 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 では、クライアントは接続を開き、リクエストを送信してサーバーからの応答を待ちます。

リクエストを読むには、2 つのオプションがあります。BufferedReader を使用するか、バイトごとに読み取ります。BufferedReader の方が簡単です。すべての行の文字列を取得し、簡単に分割したり、文字を置き換えたりすることができます;)

すべてのバイトを読み取ると少し速くなりますが、1 秒間に大量のリクエストを処理する必要がある場合にのみ関係があります。これよりも、実際に違いを生むことができます。私はあなたが知っているようにこの情報を入れただけです;)

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 を解析する必要があるとおっしゃいましたが、単純なフレームワーク (http://www.simpleframework.org) を使用する方がよいかもしれません。これは組み込み HTTP サーバーのようなものです。チュートリアルを参照してください。リクエスト オブジェクトが提供され、そこから URL のパラメータを簡単に取得できます。

于 2012-04-04T04:10:26.063 に答える