无法从 httpExchange 检索输入流数据
Unable to retrieve input stream data from httpExchange
我已经为一个 HTTP 服务器编写了一个代码,它应该根据客户端输入向客户端发送响应。
我已经写了两次相同的代码,一次使用简单的套接字连接,第二次使用 com.sun.net.httpserver
。
基于简单套接字的代码工作正常,我能够使用以下方法读取来自客户端的请求:
DataInputStream in = new DataInputStream (threadSocket.getInputStream());
int ln = in.available();
byte [] bytes = new byte [ln];
in.read(bytes);
String msg = new String(bytes);
但是,当我尝试使用 httpserver 时,我无法从客户端获得任何输入。
这是 http 服务器处理程序的代码:
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 .......
}
}
目前,我正在尝试使用来自 HttpExchange.getRequestBody()
的输入流,但它始终为空。我也试过 httpExchange.getRequestURI().getQuery()
但它也总是空的。
来自客户端的输入如下所示:
GET / HTTP/1.0
User-Agent: NTRIP GnssSurferV1.10
Authorization: Basic
我做错了什么,我该如何解决?任何帮助将不胜感激。
您应该关闭 HttpExchange
。
另请注意,您使用 available()
的方式很棘手。它returns
an estimate of the number of bytes that can be read ...
和:
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.
完整示例(不完全是您的用例,但它回答了您的问题):
/**
* 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();
}
我已经为一个 HTTP 服务器编写了一个代码,它应该根据客户端输入向客户端发送响应。
我已经写了两次相同的代码,一次使用简单的套接字连接,第二次使用 com.sun.net.httpserver
。
基于简单套接字的代码工作正常,我能够使用以下方法读取来自客户端的请求:
DataInputStream in = new DataInputStream (threadSocket.getInputStream());
int ln = in.available();
byte [] bytes = new byte [ln];
in.read(bytes);
String msg = new String(bytes);
但是,当我尝试使用 httpserver 时,我无法从客户端获得任何输入。
这是 http 服务器处理程序的代码:
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 .......
}
}
目前,我正在尝试使用来自 HttpExchange.getRequestBody()
的输入流,但它始终为空。我也试过 httpExchange.getRequestURI().getQuery()
但它也总是空的。
来自客户端的输入如下所示:
GET / HTTP/1.0
User-Agent: NTRIP GnssSurferV1.10
Authorization: Basic
我做错了什么,我该如何解决?任何帮助将不胜感激。
您应该关闭 HttpExchange
。
另请注意,您使用 available()
的方式很棘手。它returns
an estimate of the number of bytes that can be read ...
和:
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.
完整示例(不完全是您的用例,但它回答了您的问题):
/**
* 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();
}