如何在httpcomponents NIO服务器中以块的形式读取请求?

时间:2015-01-16 23:22:56

标签: apache-httpcomponents

我正在使用httpcomponenets nio服务器来处理发布请求。

以下是示例代码。它使用EntityUtils.toByteArray()获取字节数组中的完整数据。如果请求者发送大文件,则会失败。

我无法弄清楚如何以块的形式读取请求中的数据。 HttpEntity.getContent()。read()始终返回null

    public static void main(String[] args) throws Exception {
       int port = 8280;

       // Create HTTP protocol processing chain
       HttpProcessor httpproc = HttpProcessorBuilder.create()
           .add(new ResponseDate())
           .add(new ResponseServer("Test/1.1"))
           .add(new ResponseContent())
           .add(new ResponseConnControl()).build();
       // Create request handler registry
       UriHttpAsyncRequestHandlerMapper reqistry = new UriHttpAsyncRequestHandlerMapper();
       // Register the default handler for all URIs
       reqistry.register("/test*", new RequestHandler());
       // Create server-side HTTP protocol handler
       HttpAsyncService protocolHandler = new HttpAsyncService(httpproc, reqistry) {

           @Override
           public void connected(final NHttpServerConnection conn) {
               System.out.println(conn + ": connection open");
               super.connected(conn);
           }

           @Override
           public void closed(final NHttpServerConnection conn) {
               System.out.println(conn + ": connection closed");
               super.closed(conn);
           }

       };
       // Create HTTP connection factory
       NHttpConnectionFactory<DefaultNHttpServerConnection> connFactory;

           connFactory = new DefaultNHttpServerConnectionFactory(
               ConnectionConfig.DEFAULT);
       // Create server-side I/O event dispatch
       IOEventDispatch ioEventDispatch = new DefaultHttpServerIODispatch(protocolHandler, connFactory);
       // Set I/O reactor defaults
       IOReactorConfig config = IOReactorConfig.custom()
           .setIoThreadCount(1)
           .setSoTimeout(3000)
           .setConnectTimeout(3000)
           .build();
       // Create server-side I/O reactor
       ListeningIOReactor ioReactor = new DefaultListeningIOReactor(config);
       try {
           // Listen of the given port
           ioReactor.listen(new InetSocketAddress(port));
           // Ready to go!
           ioReactor.execute(ioEventDispatch);
       } catch (InterruptedIOException ex) {
           System.err.println("Interrupted");
       } catch (IOException e) {
           System.err.println("I/O error: " + e.getMessage());
       }
       System.out.println("Shutdown");
   }
public static class RequestHandler implements HttpAsyncRequestHandler<HttpRequest> {
   public void handleInternal(HttpRequest httpRequest, HttpResponse httpResponse, HttpContext httpContext) throws HttpException, IOException {

       HttpEntity entity = null;
       if (httpRequest instanceof HttpEntityEnclosingRequest)
           entity = ((HttpEntityEnclosingRequest)httpRequest).getEntity();

       byte[] data;
       if (entity == null) {
           data = new byte [0];
       } else {
           data = EntityUtils.toByteArray(entity);
       }

       System.out.println(new String(data));

       httpResponse.setEntity(new StringEntity("success response"));
   }

   @Override public HttpAsyncRequestConsumer<HttpRequest> processRequest(HttpRequest request, HttpContext context) throws HttpException, IOException {
       return new BasicAsyncRequestConsumer();
   }

   @Override
   public void handle(HttpRequest request, HttpAsyncExchange httpExchange, HttpContext context) throws HttpException, IOException {
       HttpResponse response = httpExchange.getResponse();
       handleInternal(request, response, context);
       httpExchange.submitResponse(new BasicAsyncResponseProducer(response));

   }
}

1 个答案:

答案 0 :(得分:0)

如果您希望完全控制请求处理,请考虑实施自定义AbstractAsyncRequestConsumer而不是BasicAsyncRequestConsumer

您可以使用这些类作为起点[1] [2]。请注意,这些是响应消费者,但可以使用相同的方法来创建自定义请求消费者:

[1] http://hc.apache.org/httpcomponents-asyncclient-4.1.x/httpasyncclient/xref/org/apache/http/nio/client/methods/AsyncCharConsumer.html

[2] http://hc.apache.org/httpcomponents-asyncclient-4.1.x/httpasyncclient/xref/org/apache/http/nio/client/methods/AsyncByteConsumer.html