URL使用Runnable类解析Java服务器

时间:2012-04-04 01:52:51

标签: java url runnable

如何使用这样的系统解析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();

}

}

3 个答案:

答案 0 :(得分:2)

到目前为止,你做得很好。

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

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

您需要的所有内容都可以在String类中找到,用于解析数据。

答案 1 :(得分: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服务器,您可以查看该教程。它将为您提供一个请求对象,您可以从中轻松获取URL中的参数。

答案 2 :(得分:-2)

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

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

,请参阅以下文章