I have wrote a code for an http server that suppose to send a respond to the client based on client input.
I have wrote the same code twice, once using simple socket connection and the second one using com.sun.net.httpserver
.
The code based on the simple socket works fine and I am able to read the requests coming from the client using:
DataInputStream in = new DataInputStream (threadSocket.getInputStream());
int ln = in.available();
byte [] bytes = new byte [ln];
in.read(bytes);
String msg = new String(bytes);
However, when I am trying to use the httpserver I can not get any input from the client.
This is the code for the http server hendler:
static class ntripHandler implements HttpHandler {
public void handle(HttpExchange t){
try {
int ln = t.getRequestBody().available();
byte [] bt = new byte [ln];
t.getRequestBody().read(bt);
String msg = new String(bt);
System.out.println(msg);
}
catch (IOException ex) {System.out.println(ex);}
//// some operations sholuld be made here .......
}
}
Currently, I am trying to use the input stream from the HttpExchange.getRequestBody()
but it is always null. I have also tried the httpExchange.getRequestURI().getQuery()
but it is always null as well.
The input from the client looks like this:
GET / HTTP/1.0
User-Agent: NTRIP GnssSurferV1.10
Authorization: Basic
What am I doing wrong and how can I fix it? Any help would be appreciated.
You should close the HttpExchange
.
Also note that the way you use available()
is tricky. It returns
an estimate of the number of bytes that can be read ...
and:
Note that while some implementations of {@code InputStream} will return the total number of bytes in the stream, many will not. It is never correct to use the return value of this method to allocate a buffer intended to hold all data in this stream.
Complete example (not exectly you use case, but it answers your question):
/**
* To test:
*
* ```` bash
* $ curl -v -H "Content-Type: application/json" \
* -d '{"name":"Testing!"}' http://localhost:8000
* ````
*/
public static void main(String[] args) throws IOException {
// Creates a basic HTTP server, with default Executor and system default socket
// backlog (second parameter in create method, 0)
final HttpServer server = HttpServer.create(
new InetSocketAddress("localhost", 8000), 0);
// context MUST start with "/". Root context is just "/"
// HttpHandler implemented as lambda, note that HttpHandler#handle() throws an
// IOException, so no need to catch it
server.createContext("/", (he) -> {
try {
System.out.println(he.getRequestURI());
final InputStream in = he.getRequestBody();
final OutputStream out = he.getResponseBody();
// first send header, than response body, if any
// use default buffer size suited for your use case
final byte[] buffer = new byte[in.available() == 0 ? 1024 : in.available()];
System.out.println("buffer size=" + buffer.length);
// preferrable, specify *exact* size of response body. If not known, use 0
// < HTTP/1.1 200 OK
// < Date: Thu, 21 Jul 2016 08:14:25 GMT
// < Transfer-encoding: chunked
// he.sendResponseHeaders(200, 0);
// int length;
// while ((length = in.read(buffer, 0, buffer.length)) >= 0) {
// out.write(buffer, 0, length);
// }
// better way of doing it: buffer response body and set content length
// < HTTP/1.1 200 OK
// < Date: Thu, 21 Jul 2016 08:11:40 GMT
// < Content-length: 19
final ByteArrayOutputStream baos = new ByteArrayOutputStream(buffer.length);
int length;
while ((length = in.read(buffer, 0, buffer.length)) >= 0) {
baos.write(buffer, 0, length);
}
he.sendResponseHeaders(200, baos.size());
baos.writeTo(out); // no need to close() of flush() ByteArrayOutputStream
} finally {
// Essential: HttpExchange must be closed
he.close();
}
});
server.start();
}