将命令发送到http服务器

时间:2015-10-24 14:42:42

标签: java http server client send

晚上好,我在这里得到了这个服务器

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.util.concurrent.atomic.AtomicInteger;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;

public class Test {

public static void main(String[] args) throws Exception {
    HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0);
    server.createContext("/test", new MyHandler());
    server.setExecutor(null); // creates a default executor
    server.start();
}

static class MyHandler implements HttpHandler {
    AtomicInteger atomicInteger = new AtomicInteger(0); 
    int theValue = atomicInteger.get(); 
    @Override
    public void handle(HttpExchange t) throws IOException {
    String response = String.format("Besuche: %d%n", atomicInteger.addAndGet(1));
        t.sendResponseHeaders(200, response.length());
        OutputStream os = t.getResponseBody();
        os.write(response.getBytes());
        os.close();
    }
}


}

它计算我在网站上进行的每次访问http://localhost:8000/test 现在我有一个客户端在我的控制台中向我显示服务器的内容。

import java.net.*;
import java.io.*;

public class URLConnectionReader {
public static void main(String[] args) throws Exception {
    URL test = new URL("http://localhost:8000/test");
    URLConnection connect = test.openConnection();
    BufferedReader in = new BufferedReader(new InputStreamReader(connect.getInputStream()));
    String inputLine;

    while ((inputLine = in.readLine()) != null) 
        System.out.println(inputLine);
    in.close();
}
}

我希望客户端向服务器发送一个命令,该命令会重置服务器上的计数器。我可以找到这个here,但我不知道如何在我的情况下实现这一点。我希望有人能解释我现在能做些什么。

1 个答案:

答案 0 :(得分:1)

在您提供的代码中,MyHandler的方法handle处理/test路径的请求。因此,首先要确定的是,是否要在同一路径或不同路径上接收 reset 命令?

如果你想在同一条路径上处理,那么你需要修改MyHandler以区分增加atomicInteger中存储的数量的请求 - 让我们调用GET命令,以及重置计数器的请求 - 让我们调用POST命令。看看我们做了什么?我们使用了两个HTTP request methods来区分这两个命令。现在您想要更改MyHandler来实现它。在handle方法中,您在t参数中收到HttpExchange个对象,其中包含getRequestMethod方法。因此代码看起来像:

@Override
public void handle(final HttpExchange t) throws IOException {
    final String response;

    final String requestMethod = t.getRequestMethod();
    if ("GET".equals(requestMethod)) {
        response = String.format("Besuche: %d%n", atomicInteger.addAndGet(1));
    }
    else if ("POST".equals(requestMethod)) {
        atomicInteger.set(0);

        response = "Reset to 0";
    }
    else {
        throw new IOException("Unsupported method");
    }

    t.sendResponseHeaders(200, response.length());
    final OutputStream os = t.getResponseBody();
    os.write(response.getBytes());
    os.close();
}

如果你想处理不同的路径,让我们说/reset,你需要为main方法添加注册该路径的另一个处理程序:

server.createContext("/reset", new ResetHandler());

现在在该处理程序和现有处理程序中,您需要共享相同的程序状态 - 相同的AtomicInteger引用。最好通过在AtomicInteger方法中创建main并使用处理程序的构造函数将其传递给两个处理程序来实现。这看起来像是:

static class MyHandler implements HttpHandler {

    private final AtomicInteger counter;

    public MyHandler(final AtomicInteger counter) {
        this.counter = counter;
    }

    @Override
    public void handle(final HttpExchange t) throws IOException {
        // ... same code, only reference the counter
    }
}

static class ResetHandler implements HttpHandler {
    private final AtomicInteger counter;

    public ResetHandler(final AtomicInteger counter) {
        this.counter = counter;
    }

    @Override
    public void handle(final HttpExchange exchange) throws IOException {
        counter.set(0);

        exchange.sendResponseHeaders(200, 2);
        exchange.getResponseBody().write("OK".getBytes());
    }
}

main方法中:

final AtomicInteger counter = new AtomicInteger(0);
server.createContext("/test", new MyHandler(counter));
server.createContext("/reset", new ResetHandler(counter));

还有其他可能,例如使用HTTP参数或不同的方法,但这应该可以帮助您入门。

已编辑添加: 在客户端中,您可以像这样指定请求方法:

final URL test = new URL("http://localhost:8000/test");
final HttpURLConnection connect = (HttpURLConnection) test.openConnection();
connect.setRequestMethod("POST");