无法从 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();
}