向http服务器发送命令

Send Command to http server

晚上好,我得到了这台服务器

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 但我不知道如何在我的案例中实现它。我希望有人能解释我现在能做什么。

在您提供的代码中,MyHandler 的方法 handle 处理对 /test 路径的请求。所以你应该决定的第一件事是你是想在同一路径上还是在不同的路径上接收 reset 命令?

如果你想在同一个路径上处理,那么你需要修改MyHandler来区分增加存储在atomicInteger中的数量的请求 - 让我们称之为GET 命令,以及重置计数器的请求 - 让我们调用该 POST 命令。看看我们做了什么?我们使用了两种HTTP request methods to differentiate between the two commands. Now you want to change the MyHandler to implement that. On the handle method you receive HttpExchange object in the t parameter that has the 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 引用。这最好通过在 main 方法中创建 AtomicInteger 并使用处理程序的构造函数将其传递给两个处理程序来实现。这看起来像:

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");