hc-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Apache Wiki <wikidi...@apache.org>
Subject [Httpcomponents Wiki] Update of "HttpCoreTutorial" by OlegKalnichevski
Date Tue, 21 Oct 2008 18:41:51 GMT
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


Mime
View raw message