Good evening, I got this Server here
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();
}
}
}
Its counting every visit i do on the website http://localhost:8000/test Now i have a client which shows me the content of the server in my console.
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();
}
}
I want the client to send the server a command which resets the counter on the server. I could just find this here but i dont know how to implement this in my case. I hope someone can explain me what i can do now.
In the code you've given, MyHandler
's method handle
handles the requests for the /test
path. So first thing you should decide upon is if you want to receive the reset command on the same path or on a different one?
If you want to handle on the same path, then you need to modify the MyHandler
to differentiate between the request to increase the number stored in atomicInteger
- let's call that GET
command, and the request to reset the counter - let's call that POST
command. See what we have done? We have used two 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
method. So the code would look something like:
@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();
}
If you want to handle on a different path, let's say on /reset
, you need to register another handler for that path i the main
method add:
server.createContext("/reset", new ResetHandler());
Now in that handler and in the existing handler you need to share the same state of the program - the same AtomicInteger
reference. This is best accomplished by creating the AtomicInteger
in the main
method and passing it to the two handlers using the handler's constructor. This would look something like:
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());
}
}
And in the main
method:
final AtomicInteger counter = new AtomicInteger(0);
server.createContext("/test", new MyHandler(counter));
server.createContext("/reset", new ResetHandler(counter));
There are other possibilities like using HTTP parameters or different methods, but this should get you started.
Edited to add: In the client you can specify the request method like this:
final URL test = new URL("http://localhost:8000/test");
final HttpURLConnection connect = (HttpURLConnection) test.openConnection();
connect.setRequestMethod("POST");