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

------------------------------------------------------------------------------
- = Introduction =
+ ----
+ [[TableOfContents]]
+ ----
  
- == HttpCore goals and scope ==
+ = Scope =
  
-     * A consisntent API for building client side and server side HTTP services
+  * A consistent API for building client / proxy / server side HTTP services
-     
+  * A consistent API for building both synchronous and asynchronous HTTP 
services
-     * A set of low level HTTP transport components based on blocking and 
non-blocking 
+  * A set of low level components based on blocking (classic) and non-blocking 
(NIO) I/O models 
-     I/O models
-     
+ 
+ = Goals =
+ 
+  * Implementation of the most fundamental HTTP transport aspects
+  * Balance between good performance and clarify and expressiveness of API
-     * small, predictable memory footprint
+  * Small (predictable) memory footprint
-     
-     * self-contained library with no external dependencies
+  * Self contained library (no external dependencies beyond JRE)
+ 
+ == What HttpCore is NOT ==
+ 
+  * Replacement for !HttpClient
+  * A replacement for a Servlet container and a competitor to the Servlet API
  
  = Fundamentals =
-  
+ 
  == HTTP messages ==
  
  === Structure ===
  
+ A HTTP message consists of a head and an optional body. The message head of 
an HTTP request consists of a request line and a collection of header fields. 
The message head of an HTTP response consists of a status line and a collection 
of header fields. All HTTP messages must include the protocol version. Some 
HTTP messages can optionally enclose a content body.
-     A HTTP message consists of a head and an optional body. The message head 
of an HTTP 
-     request consists of a request line and a collection of header fields. The 
message 
-     head of an HTTP response consists of a status line and a collection of 
header fields.
-     All HTTP messages must include the protocol version.
  
+ !HttpCore defines HTTP message object model that closely follows the 
definition and provides an extensive support for serialization (formatting) and 
deserialization (parsing) of HTTP message elements.
+ 
- === Common operations ===
+ === Basic operations ===
  
+ ==== HTTP request properties ====
-     Description of basic header operations: add header, remove header, set 
header, 
-     enumerate headers
  
+ HTTP request is a message sent from the client to the server. The first line 
of that message includes the method to be applied to the resource, the 
identifier of the resource, and the protocol version in use.
+ 
+ {{{
+ HttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1);
+ 
+ System.out.println(request.getRequestLine().getMethod());
+ System.out.println(request.getRequestLine().getUri());
+ System.out.println(request.getProtocolVersion());
+ System.out.println(request.getRequestLine().toString());
+ }}}
+ 
+ stdout >
+ {{{
+ GET
+ /
+ HTTP/1.1
+ GET / HTTP/1.1
+ }}}
+ 
+ ==== HTTP response properties ====
+ 
+ HTTP response is a message sent by the server back to the client after having 
received and interpreted a request message. The first line of that message 
consists of the protocol version followed by a numeric status code and its 
associated textual phrase.
+ 
+ {{{
+ HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 
HttpStatus.SC_OK, "OK");
+ 
+ System.out.println(response.getProtocolVersion());
+ System.out.println(response.getStatusLine().getStatusCode());
+ System.out.println(response.getStatusLine().getReasonPhrase());
+ System.out.println(response.getStatusLine().toString());
+ }}}
+ 
+ stdout >
+ {{{
+ HTTP/1.1
+ 200
+ OK
+ HTTP/1.1 200 OK
+ }}}
+ 
+ ==== HTTP message common properties and methods ====
+ 
+ An HTTP message can contain a number of headers describing properties of the 
message such as the content length, content type and so on. !HttpCore provides 
methods to retrieve, add, remove and enumerate headers. 
+ 
+ {{{
+ HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 
HttpStatus.SC_OK, "OK");
+ response.addHeader("Set-Cookie", "c1=a; path=/; domain=localhost");
+ response.addHeader("Set-Cookie", "c2=b; path=\"/\", c3=c; 
domain=\"localhost\"");
+ Header h1 = response.getFirstHeader("Set-Cookie");
+ System.out.println(h1);
+ Header h2 = response.getLastHeader("Set-Cookie");
+ System.out.println(h2);
+ Header[] hs = response.getHeaders("Set-Cookie");
+ System.out.println(hs.length);
+ }}}
+ 
+ stdout >
+ {{{
+ Set-Cookie: c1=a; path=/; domain=localhost
+ Set-Cookie: c2=b; path="/", c3=c; domain="localhost"
+ 2
+ }}}
+ 
+ There is an efficient way to obtain all headers of a given type using the 
!HeaderIterator interface.
+ 
+ {{{
+ HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 
HttpStatus.SC_OK, "OK");
+ response.addHeader("Set-Cookie", "c1=a; path=/; domain=localhost");
+ response.addHeader("Set-Cookie", "c2=b; path=\"/\", c3=c; 
domain=\"localhost\"");
+ 
+ HeaderIterator it = response.headerIterator("Set-Cookie");
+ 
+ while (it.hasNext()) {
+     System.out.println(it.next());
+ }
+ }}}
+ 
+ stdout >
+ {{{
+ Set-Cookie: c1=a; path=/; domain=localhost
+ Set-Cookie: c2=b; path="/", c3=c; domain="localhost"
+ }}}
+ 
+ It also provides convenience methods to parse HTTP messages into individual 
header elements.
+ 
+ {{{
+ HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 
HttpStatus.SC_OK, "OK");
+ response.addHeader("Set-Cookie", "c1=a; path=/; domain=localhost");
+ response.addHeader("Set-Cookie", "c2=b; path=\"/\", c3=c; 
domain=\"localhost\"");
+ 
+ HeaderElementIterator it = new BasicHeaderElementIterator(
+         response.headerIterator("Set-Cookie"));
+ 
+ while (it.hasNext()) {
+     HeaderElement elem = it.nextElement(); 
+     System.out.println(elem.getName() + " = " + elem.getValue());
+     NameValuePair[] params = elem.getParameters();
+     for (int i = 0; i < params.length; i++) {
+         System.out.println(" " + params[i]);
+     }
+ }
+ }}}
+ 
+ stdout >
+ {{{
+ c1 = a
+  path=/
+  domain=localhost
+ c2 = b
+  path=/
+ c3 = c
+  domain=localhost
+ }}}
+ 
+ HTTP headers get tokenized into individual header elements on demand only. 
HTTP headers received over an HTTP connection are stored internally as an array 
of chars and parsed lazily only then their properties are accessed. 
+ 
+ The char array backing the header can be obtained using the optional 
!FormattedHeader interface.
+ 
+ {{{
+ Header h1 = response.getFirstHeader("Content-Type");
+ if (h1 instanceof FormattedHeader) {
+     CharArrayBuffer buf = ((FormattedHeader) h1).getBuffer();
+     System.out.println(buf);
+ }
+ }}}
+ 
+ 
- === HTTP entity ===
+ == HTTP entity ==
  
-     Properties of an HTTP entity. Types of HTTP entities. Streaming entities. 
Repeatable
-     entities. Entity wrapping.
+ HTTP messages can carry a content entity associated with the request or 
response. Entities can be found in some requests and in some responses, where 
they are optional. Requests that use entities are referred to as entity 
enclosing requests. HTTP specification defines two entity enclosing methods: 
POST and PUT. Responses are usually expected to enclose a content entity. There 
are exceptions to this rule such as responses to HEAD method and 204 No 
Content, 304 Not Modified, 205 Reset Content responses.
+ 
+ !HttpCore distinguishes three kinds of entities, depending on where their 
content originates: 
+ 
+   a. streamed: The content is received from a stream, or generated on the 
fly. In particular, this category includes entities being received from a 
connection. Streamed entities are generally not repeatable. 
+   a. self-contained: The content is in memory or obtained by means that are 
independent from a connection or other entity. Self-contained entities are 
generally repeatable. 
+   a. wrapping: The content is obtained from another entity. 
+ 
+ This distinction is important for connection management with incoming 
entities. For entities that are created by an application and only sent using 
the !HttpCore framework, the difference between streamed and self-contained is 
of little importance. In that case, it is suggested to consider non-repeatable 
entities as streamed, and those that are repeatable as self-contained.
+ 
+ === Repeatable entities ===
+ 
+ An entity can be repeatable, meaning it's content can be read more than once. 
This is only possible with self contained entities (like !ByteArrayEntity or 
!StringEntity).
+ 
+ === Using HTTP entities ===
+ 
+ Since an entity can represent both binary and character content, it has 
support for character encodings (to support the latter, ie. character content).
+ 
+ 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.
+ 
+ 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.
+ 
+ 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.
+ 
+ When creating an entity for a outgoing message, this meta data has to be 
supplied by the creator of the entity.
+ 
+ {{{
+ StringEntity myEntity = new StringEntity("important message", "UTF-8");
+ 
+ System.out.println(myEntity.getContentType());
+ System.out.println(myEntity.getContentLength());
+ System.out.println(EntityUtils.getContentCharSet(myEntity));
+ System.out.println(EntityUtils.toString(myEntity));
+ System.out.println(EntityUtils.toByteArray(myEntity).length);
+ }}}
+ 
+ stdout >
+ {{{
+ Content-Type: text/plain; charset=UTF-8
+ 17
+ UTF-8
+ important message
+ 17
+ }}}
+ 
+ === 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. 
+ 
+ Alternatively you 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.
+ 
+ These classes include the following implementations provided by !HttpCore:
+   a. [#BasicHttpEntity BasicHttpEntity]
+   a. [#BufferedHttpEntity BufferedHttpEntity]
+   a. [#ByteArrayEntity ByteArrayEntity]
+   a. [#EntityTemplate EntityTemplate]
+   a. [#FileEntity FileEntity]
+   a. [#InputStreamEntity InputStreamEntity]
+   a. [#StringEntity StringEntity]
+   a. [#AbstractHttpEntity AbstractHttpEntity]
+   a. [#HttpEntityWrapper HttpEntityWrapper]
+ 
+ [[Anchor(BasicHttpEntity)]]
+ === BasicHttpEntity ===
+ 
+ This is exactly as the name implies, a basic entity that represents an 
underlying stream. This is generally the entities received from HTTP responses.
+ 
+ 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.
+ 
+ {{{
+ BasicHttpEntity myEntity = new BasicHttpEntity();
+ myEntity.setContent(someInputStream);
+ myEntity.setContentLength(340); // sets the length to 340
+ }}}
+ 
+ [[Anchor(ByteArrayEntity)]]
+ === ByteArrayEntity ===
+ 
+ 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!!";
+ ByteArrayEntity myEntity = new ByteArrayEntity(myData.getBytes());
+ }}}
+ 
+ [[Anchor(StringEntity)]]
+ === StringEntity ===
+ 
+ Very simple entity. It's is a 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.
+ 
+ {{{
+ StringBuffer sb = new StringBuffer();
+ Map<String, String> env = System.getenv();
+ for (Entry<String, String> envEntry : env.entrySet()) {
+     sb.append(envEntry.getKey()).append(": 
").append(envEntry.getValue()).append("\n");
+ }
+ 
+ // construct without a character encoding
+ HttpEntity myEntity1 = new StringEntity(sb.toString());
+ 
+ // alternatively construct with an encoding
+ HttpEntity myEntity2 = new StringEntity(sb.toString(), "UTF-8");
+ }}}
+ 
+ [[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.
+ 
+ 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() {
+ 
+     public void writeTo(OutputStream out) throws IOException {
+       out.write("ContentProducer rocks! ".getBytes());
+       out.write(("Time requested: " + new Date()).getBytes());
+     }
+     
+ };
+ 
+ HttpEntity myEntity = new EntityTemplate(myContentProducer);
+ myEntity.writeTo(System.out);
+ }}}
+ 
+ stdout >
+ {{{
+ ContentProducer rocks! Time requested: Fri Sep 05 12:20:22 CEST 2008
+ }}}
+ 
+ [[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".
+ 
+ {{{File staticFile = new File("/path/to/myapp.jar");
+ HttpEntity entity = new FileEntity(staticFile, "application/java-archive");
+ }}}
+ 
+ [[Anchor(InputStreamEntity)]]
+ === InputStreamEntity ===
+ 
+ An entity that reads it's content from an input stream. It is constructed by 
supplied the input stream as well as the content length.
+ 
+ The content length is used to limit the amount of data read from the 
!InputStream. If the length matches the content length available on the input 
stream, then all data will be sent. Alternatively a negative content length 
will read all data from the input stream, which is the same as supplying the 
exact content length, so the length is most often used to limit the length.
+ 
+ {{{
+ InputStream instream = getSomeInputStream();
+ InputStreamEntity myEntity = new InputStreamEntity(instream, 16);
+ }}}
+ 
+ [[Anchor(AbstractHttpEntity)]]
+ === AbstractHttpEntity ===
+ 
+ This is the base class for streaming and self contained entities. It provides 
all the commonly used attributes used by these entities, like contentEncoding, 
contentType and the chunked flag.
+ 
+ [[Anchor(HttpEntityWrapper)]]
+ === HttpEntityWrapper ===
+ 
+ This is the base class for creating wrapped entities. It contains an instance 
variable wrappedEntity which holds the instance to the wrapped entity.
+ 
+ [[Anchor(BufferedHttpEntity)]]
+ === BufferedHttpEntity ===
+ 
+ !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.
+ 
+ {{{BasicHttpEntity myNonRepeatableEntity = new BasicHttpEntity();
+ myNonRepeatableEntity.setContent(someInputStream);
+ BufferedHttpEntity myBufferedEntity = new 
BufferedHttpEntity(myNonRepeatableEntity);
+ }}}
  
  == HTTP connections ==
  
-     HTTP connections are responsible for HTTP message serialization and 
deserialization
+ HTTP connections are responsible for HTTP message serialization and 
deserialization. One should rarely need to use HTTP connection objects 
directly. There are higher level protocol components intended for execution and 
processing of HTTP requests. However, in some cases direct interaction with 
HTTP connections may be necessary for instance to access properties such as the 
connection status, the socket timeout or the local and remote addresses.
+ 
+ HTTP connections are NOT threading safe! It is strongly recommended to limit 
all interactions with HTTP connection objects to one thread. The only method of 
!HttpConnection interface and its sub-interfaces, which is safe to invoke from 
another thread, is !HttpConnection#shutdown().
+ 
+ === Using blocking HTTP connections ===
+ 
+ !HttpCore does not provide full support for opening connections because the 
process of establishing a new connection especially on the client side can be 
very complex involving one or several authenticating or/and tunneling proxies. 
Instead, HTTP connection objects can be bound to an arbitrary network socket. 
+ 
+ {{{
+ BasicHttpParams params = new BasicHttpParams();
+ DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
+ conn.bind(mySocket, params);
+ conn.isOpen();
+ HttpConnectionMetrics metrics = conn.getMetrics();
+ metrics.getRequestCount();
+ metrics.getResponseCount();
+ metrics.getReceivedBytesCount();
+ metrics.getSentBytesCount();
+ }}}
+ 
+ === Terminating HTTP connections ===
+ 
+ HTTP connections can be terminated either gracefully by calling 
!HttpConnection#close() or forcibly by calling !HttpConnection#shutdown(). The 
former tries to flush all buffered data prior to terminating the connection and 
may block indefinitely. The !HttpConnection#close() method is NOT threading 
safe. The latter terminates the connection without flushing internal buffers 
and returns control to the caller as soon as possible without blocking for 
long. The !HttpConnection#shutdown() method is expected to be threading safe.
+ 
+ === Content transfer ===
+ 
+     * Content-Length delimited
+     
+     * Identity coding
+     
+     * Chunk coding
  
  === Parsing and formatting of HTTP messages ===
  
      HttpMessageParser / HttpMessageWriter interfaces
+         
-     
- === Content transfer ===
- 
-     * Content-Length delimited
-     
-     * Identity coding
-     
-     * Chunk coding
-     
  == HTTP protocol processors ==
  
  === Protocol interceptor ===

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to