2015-01-16 37 views
0

我正在使用httpcomponenets nio服務器來處理髮布請求。如何在httpcomponents NIO服務器中讀取塊中的請求?

下面是示例代碼。它使用EntityUtils.toByteArray()獲取字節數組中的完整數據。如果請求者發送大文件,這將失敗。

我無法弄清楚如何以塊讀取請求中的數據。 HttpEntity.getContent()。閱讀()始終返回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)); 

    } 
} 

回答

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

+0

感謝您的答覆。我會檢查這些。 –

相關問題