代码之家  ›  专栏  ›  技术社区  ›  user4559332

无法从httpExchange检索输入流数据

  •  0
  • user4559332  · 技术社区  · 8 年前

    我已经为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() 但它总是空的。我还尝试了 httpExchange.getRequestURI().getQuery() 但它也总是空的。

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

    我做错了什么?我该如何纠正?任何帮助都将不胜感激。

    1 回复  |  直到 8 年前
        1
  •  0
  •   rmuller    8 年前

    您应该关闭 HttpExchange .

    还请注意,您使用的方法 available() 很棘手。它会返回

    可读取字节数的估计。。。

    和:

    注意,虽然{@codeInputStream}的一些实现将返回 流中的总字节数,很多不会。它是

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

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