无法从httpExchange检索输入流数据

时间:2016-07-21 07:21:20

标签: java inputstream httpserver simplehttpserver get-request

我为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服务器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 .......

    }
}

目前,我正在尝试使用来自HttpExchange.getRequestBody()的输入流,但它始终为null。我也尝试了httpExchange.getRequestURI().getQuery(),但它也总是为空。

来自客户端的输入如下所示: GET / HTTP/1.0 User-Agent: NTRIP GnssSurferV1.10 Authorization: Basic

我做错了什么,我该如何解决?任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

您应该关闭HttpExchange

另请注意,使用available()的方式很棘手。它返回

  

估计可以读取的字节数...

  

请注意,虽然{@code InputStream}的某些实现将返回   流中的总字节数,很多都不会。它是   从不纠正使用此方法的返回值进行分配   用于保存此流中所有数据的缓冲区。

完整的例子(不是你使用案例,但它回答了你的问题):

/**
 * 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();
}