You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@hc.apache.org by Apache Wiki <wi...@apache.org> on 2008/11/17 20:47:09 UTC

[Httpcomponents Wiki] Update of "HttpCoreTutorial" by OlegKalnichevski

Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Httpcomponents Wiki" for change notification.

The following page has been changed by OlegKalnichevski:
http://wiki.apache.org/HttpComponents/HttpCoreTutorial

------------------------------------------------------------------------------
  
  ==== HTTP request handlers ====
  
- !HttpRequestHandler interface represents a routine intended to handle processing of a specific group of HTTP requests. !HttpService is designed to take care of protocol specific aspects, whereas request handlers take care of application specific HTTP processing. Their main purpose is to generate a content entity to be send back to the client in response to the given request.
+ !HttpRequestHandler interface represents a routine for processing of a specific group of HTTP requests. !HttpService is designed to take care of protocol specific aspects, whereas individual request handlers are expected to take care of application specific HTTP processing. The main purpose of a request handler is to generate a response object with a content entity to be send back to the client in response to the given request.
  
  {{{
  HttpRequestHandler myRequestHandler = new HttpRequestHandler() {
@@ -675, +675 @@

          response.setEntity(new StringEntity("some important message"));
      }
      
- });
+ };
  }}}
  
  Request handlers must be implemented threading safe. Similarly to servlets, request handlers should not use instance variables unless access to those variables is synchronized.
  
  ==== Request handler resolver ====
  
- HTTP request handlers are usually managed by a !HttpRequestHandlerResolver that matches a request URI to a request handler. !HttpCore includes an over-simplified implementation of request handler resolver based on a trivial pattern matching algorithm: !HttpRequestHandlerRegistry supports only three formats: *, <uri>* and *<uri>.
+ HTTP request handlers are usually managed by a !HttpRequestHandlerResolver that matches a request URI to a request handler. !HttpCore includes a very simple implementation of the request handler resolver based on a trivial pattern matching algorithm: !HttpRequestHandlerRegistry supports only three formats: *, <uri>* and *<uri>.
  
  {{{
  HttpService httpService;
@@ -1426, +1426 @@

  
  The !NHttpEntity will make use of the direct channel I/O whenever possible, provided the content encoder is capable of transferring data directly from a file to the socket of the underlying connection.
  
- == NHTTP protocol handlers ==
+ == Non-blocking HTTP protocol handlers ==
  
- === Asynchronous protocol handlers ===
+ === Asynchronous HTTP service handler ===
  
-     Protocol handlers that read & write out the content of messages
-     asynchronously
+ !AsyncNHttpServiceHandler is fully asynchronous HTTP service handler implementation that works with !ConsumingNHttpEntity and !ProducingNHttpEntity. The contents of HTTP headers are stored in memory, HTTP entities are streamed directly from the entities to the underlying channel (and vice versa). 
+ 
+ When using this implementation, it is important to ensure that entities supplied for writing implement !ProducingNHttpEntity. Doing so will allow the entity to be written out asynchronously. If entities supplied for writing do not implement the !ProducingNHttpEntity interface, a delegate is added that buffers the entire contents in memory. Additionally, the buffering might take place in the I/O dispatch thread, which could cause I/O to block temporarily. For best results, one must ensure that all entities set on !HttpResponses from !NHttpRequestHandlers implement !ProducingNHttpEntity.
+ 
+ If incoming requests enclose a content entity, !NHttpRequestHandlers are expected to return a !ConsumingNHttpEntity for reading the content. After the entity is finished reading the data, !NHttpRequestHandler#handle() method is called to generate a response. Similarly to other HTTP protocol handlers !AsyncNHttpServiceHandler relies on !HttpProcessor to take care of the cross-cutting protocol aspects that apply to all incoming and outgoing messages.
+ 
+ {{{
+ HttpParams params;
+ // Initialize HTTP parameters
+ HttpProcessor httpproc;
+ // Initialize HTTP processor
+ 
+ AsyncNHttpServiceHandler handler = new AsyncNHttpServiceHandler(
+         httpproc,
+         new DefaultHttpResponseFactory(),
+         new DefaultConnectionReuseStrategy(),
+         params);
+ }}}
+ 
+ ==== Non-blocking HTTP request handlers ====
+ 
+ !NHttpRequestHandler interface represents a routine for processing of a specific group of non-blocking HTTP requests. !NHttpServiceHandler implementations are expected to take care of protocol specific aspects, whereas individual request handlers are expected take care of application specific HTTP processing. The main purpose of a request handler is to generate a response object with a content entity to be send back to the client in response to the given request.
+ 
+ {{{
+ NHttpRequestHandler myRequestHandler = new NHttpRequestHandler() {
+ 
+     public ConsumingNHttpEntity entityRequest(
+             HttpEntityEnclosingRequest request, 
+             HttpContext context) throws HttpException, IOException {
+         // Buffer imcoming content in memory for simplicity 
+         return new BufferingNHttpEntity(request.getEntity(),
+                 new HeapByteBufferAllocator());
+     }
+ 
+     public void handle(
+             HttpRequest request, 
+             HttpResponse response,
+             NHttpResponseTrigger trigger,
+             HttpContext context) throws HttpException, IOException {
+         response.setStatusCode(HttpStatus.SC_OK);
+         response.addHeader("Content-Type", "text/plain");
+         response.setEntity(new NStringEntity("some important message"));
+         // Submit response immediately for simplicity
+         trigger.submitResponse(response);
+     }
+     
+ };
+ }}}
+ 
+ Request handlers must be implemented threading safe. Similarly to servlets, request handlers should not use instance variables unless access to those variables is synchronized.
+ 
+ ==== Asynchronous response trigger ====
+ 
+ The most fundamental difference of the non-blocking request handlers compared to their blocking counterparts is ability to defer transmission of the HTTP response back to the client without blocking the I/O thread by delegating the process of handling the HTTP request to a worker thread. The worker thread can use the instance of !NHttpResponseTrigger passed as a parameter to the !NHttpRequestHandler#handle method to submit a response as at a later point of time once the response becomes available.
+ 
+ {{{
+ NHttpRequestHandler myRequestHandler = new NHttpRequestHandler() {
+ 
+     public ConsumingNHttpEntity entityRequest(
+             HttpEntityEnclosingRequest request, 
+             HttpContext context) throws HttpException, IOException {
+         // Buffer imcoming content in memory for simplicity 
+         return new BufferingNHttpEntity(request.getEntity(),
+                 new HeapByteBufferAllocator());
+     }
+ 
+     public void handle(
+             final HttpRequest request, 
+             final HttpResponse response,
+             final NHttpResponseTrigger trigger,
+             final HttpContext context) throws HttpException, IOException {
+         new Thread() {
+             @Override
+             public void run() {
+                 try { Thread.sleep(10); } catch(InterruptedException ie) {}
+                 try {
+                     URI uri = new URI(request.getRequestLine().getUri());
+                     response.setStatusCode(HttpStatus.SC_OK);
+                     response.addHeader("Content-Type", "text/plain");
+                     response.setEntity(new NStringEntity("some important message"));
+                     trigger.submitResponse(response);                    
+                 } catch(URISyntaxException ex) {
+                     trigger.handleException(new HttpException("Invalid request URI: " + ex.getInput()));
+                 }
+             }
+         }.start();
+     }
+     
+ };
+ }}}
+ 
+ Please note !HttpResponse objects are not threading safe and may not be modified concurrently. Non-blocking request handlers must ensure the HTTP response cannot be accessed by more than one thread at a time.
+ 
+ ==== Non-blocking request handler resolver ====
+ 
+ The management of non-blocking HTTP request handlers is quite similar to that of blocking HTTP request handlers. Usually an instance of !NHttpRequestHandlerResolver is used to maintain a registry of request handlers and to matches a request URI to a particular request handler. !HttpCore includes only a very simple implementation of the request handler resolver based on a trivial pattern matching algorithm: !NHttpRequestHandlerRegistry supports only three formats: *, <uri>* and *<uri>.
+ 
+ {{{
+ // Initialize asynchronous protocol handler
+ AsyncNHttpServiceHandler handler;
+ 
+ NHttpRequestHandlerRegistry handlerResolver = new NHttpRequestHandlerRegistry();
+ handlerReqistry.register("/service/*", myRequestHandler1);
+ handlerReqistry.register("*.do", myRequestHandler2);
+ handlerReqistry.register("*", myRequestHandler3);
+ 
+ handler.setHandlerResolver(handlerResolver);
+ }}}
+ 
+ Users are encouraged to provide more sophisticated implementations of !NHttpRequestHandlerResolver, for instance, based on regular expressions.
  
  === Buffering protocol handlers ===
  

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org