[prev in list] [next in list] [prev in thread] [next in thread] 

List:       httpclient-commons-dev
Subject:    [Httpcomponents Wiki] Update of "HttpCoreTutorial" by OlegKalnichevski
From:       Apache Wiki <wikidiffs () apache ! org>
Date:       2008-10-21 18:41:51
Message-ID: 20081021184151.28083.42518 () eos ! apache ! org
[Download RAW message or body]

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

------------------------------------------------------------------------------
  
  The entity is created when executing a request with enclosed content or when the \
request was successful and the response body is used to send the result back to the \
client.  
- To read the content from the entity, you can either retrieve the input stream via \
the !HttpEntity#getContent() method, which returns an !InputStream, or you can supply \
an output stream to the !HttpEntity.writeTo(!OutputStream) method, which will return \
once all content has been written to the given stream. + To read the content from the \
entity, one can either retrieve the input stream via the !HttpEntity#getContent() \
method, which returns an !InputStream, or one can supply an output stream to the \
!HttpEntity.writeTo(!OutputStream) method, which will return once all content has \
been written to the given stream.  
- The !EntityUtils class exposes several static methods to more easily read the \
content or information from an entity. Instead of reading the !InputStream yourself, \
you can retrieve the whole content body in a String/byte array by using the methods \
from this class. + The !EntityUtils class exposes several static methods to more \
easily read the content or information from an entity. Instead of reading the \
!InputStream directly, one can retrieve the whole content body in a String/byte array \
by using the methods from this class.  
  When the entity was received with an incoming message, the methods \
!HttpEntity#getContentType() and !HttpEntity#getContentLength() methods can be used \
for reading the common metadata such as Content-Type and Content-Length headers (if \
they are available). Since the Content-Type header can contain a character encoding \
for text mime-types like text/plain or text/html, the \
!HttpEntity#getContentEncoding() method is used to read this information. If the \
headers aren't available, a length of -1 will be returned, and NULL for the \
content-type. If the Content-Type header is available, a Header object will be \
returned.  
@@ -214, +214 @@

  
  === Ensuring release of low level resources ===
  
- When you are finished with an entity that relies on an underlying input stream, \
it's important to execute the !HttpEntity#consumeContent() method, so as to clean up \
any available content on the stream so the connection be released to any connection \
pools. If you don't do this, other requests can't reuse this connection, since there \
are still available information on the buffer.  + When finished with an entity that \
relies on an underlying input stream, it's important to execute the \
!HttpEntity#consumeContent() method, so as to consume any available content on the \
stream, so the connection could be released to any connection pools. If the incoming \
content is not consumed fully, other requests may fail when this connection is \
re-used.   
- Alternatively you can simply check the result of !HttpEntity#isStreaming(), and \
keep reading from the input stream until it returns false.  + Alternatively one can \
simply check the result of !HttpEntity#isStreaming(), and keep reading from the input \
stream until it returns false.   
  Self contained entities will always return false with !HttpEntity#isStreaming(), as \
there is no underlying stream it depends on. For these entities \
!HttpEntity#consumeContent() will do nothing, and does not need to be called.  
  == Creating entities ==
  
- There are a few ways to create entities. You would want to do this when you \
implement custom responses, or send POST/PUT requests. + There are a few ways to \
create entities. The following implementations are provided by !HttpCore:  
- These classes include the following implementations provided by !HttpCore:
    a. [#BasicHttpEntity BasicHttpEntity]
    a. [#BufferedHttpEntity BufferedHttpEntity]
    a. [#ByteArrayEntity ByteArrayEntity]
@@ -242, +241 @@

  
  This entity has an empty constructor. After constructor it represents no content, \
and has a negative content length.  
- You need to set the content stream, and optionally the length. You can do this with \
the !BasicHttpEntity#setContent(!InputStream) and \
!BasicHttpEntity#setContentLength(long) methods respectively. + One needs to set the \
content stream, and optionally the length. This can be done with the \
!BasicHttpEntity#setContent(!InputStream) and !BasicHttpEntity#setContentLength(long) \
methods respectively.  
  {{{
  BasicHttpEntity myEntity = new BasicHttpEntity();
@@ -284, +283 @@

  [[Anchor(EntityTemplate)]]
  === EntityTemplate ===
  
- This is an entity which receives it's content from a !ContentProducer. Content \
producers are objects which produce their content on demand, by writing it out to an \
output stream. They are expected to be able produce their content every time they are \
requested to do so. So creating a !EntityTemplate, you supply a reference to a \
content producer, which effectively creates a repeatable entity. + This is an entity \
which receives it's content from a !ContentProducer. Content producers are objects \
which produce their content on demand, by writing it out to an output stream. They \
are expected to be able produce their content every time they are requested to do so. \
So creating a !EntityTemplate, one is expected to supply a reference to a content \
producer, which effectively creates a repeatable entity.  
+ There are no standard !ContentProducers in !HttpCore. It's basically just a \
convenience interface to allow wrapping up complex logic into an entity. To use this \
entity one needs to create a class that implements !ContentProducer and override the \
!ContentProducer#writeTo(!OutputStream) method. Then, an instance of custom \
!ContentProducer will be used to write the full content body to the output stream. \
For instance, an HTTP server would serve static files with the !FileEntity, but \
running CGI programs could be done with a !ContentProducer, inside which one could \
implement custom logic to supply the content as it becomes available. This way one \
doesn't need to buffer it in a string and then use a !StringEntity or \
                !ByteArrayEntity.
- There are no standard !ContentProducers in !HttpCore. It's basically just a \
convenience interface to allow wrapping up complex logic into an entity. To use this \
entity you will need to create a class that implements !ContentProducer and override \
the !ContentProducer#writeTo(!OutputStream) method. Inside this method you will write \
                the full content body to the output stream.
- 
- If you for instance made a HTTP server, you would serve static files with the \
!FileEntity, but running CGI programs can be done with a !ContentProducer, inside \
which you run the program and supply the content as it becomes available. This way \
you don't need to buffer it in a string and then use a !StringEntity or \
!ByteArrayEntity.  
  {{{
  ContentProducer myContentProducer = new ContentProducer() {
@@ -312, +309 @@

  [[Anchor(FileEntity)]]
  === FileEntity ===
  
- This entity is reads it's content body from a file. Since this is mostly used to \
stream large files of different types, you need to supply the content type of the \
file, for instance, sending a zip you would supply the content type \
"application/zip", for XML "application/xml". + This entity reads it's content body \
from a file. Since this is mostly used to stream large files of different types, one \
needs to supply the content type of the file, for instance, sending a zip one would \
supply the content type "application/zip", for XML "application/xml".  
  {{{File staticFile = new File("/path/to/myapp.jar");
  HttpEntity entity = new FileEntity(staticFile, "application/java-archive");
@@ -345, +342 @@

  
  !BufferedHttpEntity is a subclass of !HttpEntityWrapper. It is constructed by \
supplying another entity. It reads the content from the supplied entity, and buffers \
it in memory.  
- This allows you to make a repeatable entity, from a non-repeatable entity. If the \
supplied entity is already repeated, calls are simply passed through to the \
underlying entity. + This makes it possible to make a repeatable entity, from a \
non-repeatable entity. If the supplied entity is already repeated, calls are simply \
passed through to the underlying entity.  
  {{{BasicHttpEntity myNonRepeatableEntity = new BasicHttpEntity();
  myNonRepeatableEntity.setContent(someInputStream);
@@ -1312, +1309 @@

  
   * closed: triggered when the connection is closed.
  
- 
  == Non-blocking HTTP entities ==
  
- As discussed previously the process of content transfer for non-blocking \
connections works completely differently compared to that for blocking connections. \
For obvious reasons classic I/O abstraction based on inherently blocking !InputStream \
and !OutputStream classes is not applicable to the asynchronous process of data \
transfer. Therefore, non-blocking HTTP entities provide NIO specific extensions to \
the !HttpEntity interface: !ProducingNHttpEntity and !ConsumingNHttpEntity \
interfaces. Implementation classes of these interfaces may throw \
!UnsupportedOperationException from #getContent() or #writeTo() if a particular \
implementation is unable to represent its content stream as instance of !InputStream \
or cannot stream its content out to an !OutputStream + As discussed previously the \
process of content transfer for non-blocking connections works completely differently \
compared to that for blocking connections. For obvious reasons classic I/O \
abstraction based on inherently blocking !InputStream and !OutputStream classes is \
not applicable to the asynchronous process of data transfer. Therefore, non-blocking \
HTTP entities provide NIO specific extensions to the !HttpEntity interface: \
!ProducingNHttpEntity and !ConsumingNHttpEntity interfaces. Implementation classes of \
these interfaces may throw UnsupportedOperationException from #getContent() or \
#writeTo() if a particular implementation is unable to represent its content stream \
as instance of !InputStream or cannot stream its content out to an !OutputStream.  
- Producing entities; consuming entities;
+ === Content consuming non-blocking HTTP entity ===
+ 
+ !ConsumingNHttpEntity interface represents a non-blocking entity that allows \
content to be consumed from a content decoder. !ConsumingNHttpEntity extends the base \
!HttpEntity interface with a number of NIO specific notification methods: + 
+  * consumeContent: notification that content is available to be read from the \
decoder. !IOControl instance passed as a parameter to the method can be used to \
suspend input events if the entity is temporarily unable to allocate more storage to \
accommodate all incoming content. +  
+  * finish: notification that any resources allocated for reading can be released.
+ 
+ The following implementations of !ConsumingNHttpEntity provided by !HttpCore NIO:
+ 
+   a. [#BufferingNHttpEntity BufferingNHttpEntity]
+   a. [#ConsumingNHttpEntityTemplate ConsumingNHttpEntityTemplate]
+ 
+ [[Anchor(BufferingNHttpEntity)]]
+ === BufferingNHttpEntity ===
+ 
+ !BufferingNHttpEntity is a subclass of !HttpEntityWrapper that consumes all \
incoming content into a memeory memory. Once the content body has been fully received \
it can be retrieved as an InputStream via !HttpEntity#getContent(), or written to an \
output stream via !HttpEntity#writeTo(). + 
+ [[Anchor(ConsumingNHttpEntityTemplate)]]
+ === ConsumingNHttpEntityTemplate ===
+ 
+ !ConsumingNHttpEntityTemplate is a subclass of !HttpEntityWrapper that decorates \
the incoming HTTP entity and delegates the handling of incoming content to a \
!ContentListener instance. + 
+ {{{
+ static class FileWriteListener implements ContentListener {
+ 
+     private final FileChannel fileChannel;
+     private long idx = 0;
+ 
+     public FileWriteListener(File file) throws IOException {
+         this.fileChannel = new FileInputStream(file).getChannel();
-     
+     }
+ 
+     public void contentAvailable(ContentDecoder decoder, IOControl ioctrl) throws \
IOException { +         long transferred;
+         if (decoder instanceof FileContentDecoder) {
+             transferred = ((FileContentDecoder) decoder).transfer(
+                     fileChannel, idx, Long.MAX_VALUE);
+         } else {
+             transferred = fileChannel.transferFrom(
+                     new ContentDecoderChannel(decoder), idx, Long.MAX_VALUE);
+         }
+         if (transferred > 0) {
+             idx += transferred;
+         }
+     }
+ 
+     public void finished() {
+         try {
+             fileChannel.close();
+         } catch(IOException ignored) {}
+     }
+     
+ }
+ 
+ HttpEntity incomingEntity;
+ 
+ File file = new File("buffer.bin");
+ ConsumingNHttpEntity entity = new ConsumingNHttpEntityTemplate(
+         incomingEntity, 
+         new FileWriteListener(file)); 
+ }}}
+ 
+ === Content producing non-blocking HTTP entity ===
+ 
+ !ProducingNHttpEntity interface represents a non-blocking allows content to be \
written to a content encoder. !ProducingNHttpEntity extends the base !HttpEntity \
interface with a number of NIO specific notification methods: + 
+  * produceContent: notification that content can be written to the encoder. \
!IOControl instance passed as a parameter to the method can be used to temporarily \
suspend output events if the entity is unable to produce more content. Please note \
one must call !ContentEncoder#complete() to inform the underyling connection that all \
content has been written. Failure to do so could result in the entity never being \
correctly delimited.  + 
+  * finish: notification that any resources allocated for writing can be released.
+ 
+ The following implementations of !ProducingNHttpEntity provided by !HttpCore NIO:
+ 
+   a. [#NByteArrayEntity NByteArrayEntity]
+   a. [#NStringEntity NStringEntity]
+   a. [#NFileEntity NFileEntity]
+ 
+ [[Anchor(NByteArrayEntity)]]
+ === NByteArrayEntity ===
+ 
+ This is a simple self contained repeatable entity, which receives it's content from \
a given byte array. This byte array is supplied to the constructor. + 
+ {{{
+ String myData = "Hello world on the other side!!";
+ NByteArrayEntity entity = new NByteArrayEntity(myData.getBytes()); 
+ }}}
+ 
+ [[Anchor(NStringEntity)]]
+ === NStringEntity ===
+ 
+ It's is a simple, self contained, repeatable entity that retrieves it's data from a \
String object. + 
+ It has 2 constructors, one simply constructs with a given String object where the \
other also takes a character encoding for the data in the String. + 
+ {{{
+ String myData = "Hello world on the other side!!";
+ // construct without a character encoding
+ NStringEntity myEntity1 = new NStringEntity(myData);
+ // alternatively construct with an encoding
+ NStringEntity myEntity2 = new NStringEntity(myData, "UTF-8");
+ }}}
+ 
+ [[Anchor(NFileEntity)]]
+ === NFileEntity ===
+ 
+ This entity reads it's content body from a file. This class is mostly used to \
stream large files of different types, so one needs to supply the content type of the \
file to make sure the content can be correctly recognized and processed by the \
recipient. + 
+ {{{File staticFile = new File("/path/to/myapp.jar");
+ NHttpEntity entity = new NFileEntity(staticFile, "application/java-archive");
+ }}}
+ 
+ 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 ==
  
  === Asynchronous protocol handlers ===
@@ -1341, +1448 @@

  
      SSLIOSession, SSLServerIOEventDispatch, SSLClientIOEventDispatch classes
  
- 
  == Customization of the HTTP message parsing / formatting ==
  
      LineParser / LineFormatter interfaces

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


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic