| <html><head> |
| <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> |
| <title>Chapter 1. Fundamentals</title><link rel="stylesheet" type="text/css" href="css/hc-tutorial.css"><meta name="generator" content="DocBook XSL-NS Stylesheets V1.76.1"><link rel="home" href="index.html" title="HttpCore Tutorial"><link rel="up" href="index.html" title="HttpCore Tutorial"><link rel="prev" href="preface.html" title="Preface"><link rel="next" href="nio.html" title="Chapter 2. NIO extensions"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div xmlns:fo="http://www.w3.org/1999/XSL/Format" class="banner"><a class="bannerLeft" href="http://www.apache.org/" title="Apache Software Foundation"><img style="border:none;" src="images/asf_logo_wide.gif"></a><a class="bannerRight" href="http://hc.apache.org/httpcomponents-core-ga/" title="Apache HttpComponents Core"><img style="border:none;" src="images/hc_logo.png"></a><div class="clear"></div></div><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter 1. Fundamentals</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="preface.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="nio.html">Next</a></td></tr></table><hr></div><div class="chapter" title="Chapter 1. Fundamentals"><div class="titlepage"><div><div><h2 class="title"><a name="fundamentals"></a>Chapter 1. Fundamentals</h2></div></div></div> |
| |
| <div class="section" title="1.1. HTTP messages"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d5e48"></a>1.1. HTTP messages</h2></div></div></div> |
| |
| <div class="section" title="1.1.1. Structure"><div class="titlepage"><div><div><h3 class="title"><a name="d5e50"></a>1.1.1. Structure</h3></div></div></div> |
| |
| <p> |
| A HTTP message consists of a header and an optional body. The message header of an HTTP |
| request consists of a request line and a collection of header fields. The message header |
| 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. |
| </p> |
| <p> |
| HttpCore defines the HTTP message object model to closely follow this definition and |
| provides extensive support for serialization (formatting) and deserialization |
| (parsing) of HTTP message elements. |
| </p> |
| </div> |
| <div class="section" title="1.1.2. Basic operations"><div class="titlepage"><div><div><h3 class="title"><a name="d5e54"></a>1.1.2. Basic operations</h3></div></div></div> |
| |
| <div class="section" title="1.1.2.1. HTTP request message"><div class="titlepage"><div><div><h4 class="title"><a name="d5e56"></a>1.1.2.1. HTTP request message</h4></div></div></div> |
| |
| <p> |
| 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. |
| </p> |
| <pre class="programlisting"> |
| 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()); |
| </pre> |
| <p>stdout ></p> |
| <pre class="programlisting"> |
| GET |
| / |
| HTTP/1.1 |
| GET / HTTP/1.1 |
| </pre> |
| </div> |
| <div class="section" title="1.1.2.2. HTTP response message"><div class="titlepage"><div><div><h4 class="title"><a name="d5e62"></a>1.1.2.2. HTTP response message</h4></div></div></div> |
| |
| <p> |
| 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. |
| </p> |
| <pre class="programlisting"> |
| 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()); |
| </pre> |
| <p>stdout ></p> |
| <pre class="programlisting"> |
| HTTP/1.1 |
| 200 |
| OK |
| HTTP/1.1 200 OK |
| </pre> |
| </div> |
| <div class="section" title="1.1.2.3. HTTP message common properties and methods"><div class="titlepage"><div><div><h4 class="title"><a name="d5e68"></a>1.1.2.3. HTTP message common properties and methods</h4></div></div></div> |
| |
| <p> |
| 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 such headers. |
| </p> |
| <pre class="programlisting"> |
| 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); |
| </pre> |
| <p>stdout ></p> |
| <pre class="programlisting"> |
| Set-Cookie: c1=a; path=/; domain=localhost |
| Set-Cookie: c2=b; path="/", c3=c; domain="localhost" |
| 2 |
| </pre> |
| <p> |
| There is an efficient way to obtain all headers of a given type using the |
| <code class="interfacename">HeaderIterator</code> interface. |
| </p> |
| <pre class="programlisting"> |
| 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()); |
| } |
| </pre> |
| <p>stdout ></p> |
| <pre class="programlisting"> |
| Set-Cookie: c1=a; path=/; domain=localhost |
| Set-Cookie: c2=b; path="/", c3=c; domain="localhost" |
| </pre> |
| <p> |
| It also provides convenience methods to parse HTTP messages into individual |
| header elements. |
| </p> |
| <pre class="programlisting"> |
| 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]); |
| } |
| } |
| </pre> |
| <p>stdout ></p> |
| <pre class="programlisting"> |
| c1 = a |
| path=/ |
| domain=localhost |
| c2 = b |
| path=/ |
| c3 = c |
| domain=localhost |
| </pre> |
| <p> |
| HTTP headers get tokenized into individual header elements only on demand. HTTP |
| headers received over an HTTP connection are stored internally as an array of |
| characters and parsed lazily only when their properties are accessed. |
| </p> |
| </div> |
| </div> |
| <div class="section" title="1.1.3. HTTP entity"><div class="titlepage"><div><div><h3 class="title"><a name="d5e84"></a>1.1.3. HTTP entity</h3></div></div></div> |
| |
| <p> |
| HTTP messages can carry a content entity associated with the request or response. |
| Entities can be found in some requests and in some responses, as they are optional. |
| Requests that use entities are referred to as entity enclosing requests. The 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. |
| </p> |
| <p> |
| HttpCore distinguishes three kinds of entities, depending on where their content |
| originates: |
| </p> |
| <div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> |
| <p title="streamed:"> |
| <b>streamed: </b> |
| |
| 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. |
| |
| </p> |
| </li><li class="listitem"> |
| <p title="self-contained:"> |
| <b>self-contained: </b> |
| |
| The content is in memory or obtained by means that are independent from |
| a connection or other entity. Self-contained entities are generally repeatable. |
| |
| </p> |
| </li><li class="listitem"> |
| <p title="wrapping:"> |
| <b>wrapping: </b> |
| |
| The content is obtained from another entity. |
| |
| </p> |
| </li></ul></div> |
| <p> |
| 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. |
| </p> |
| <div class="section" title="1.1.3.1. Repeatable entities"><div class="titlepage"><div><div><h4 class="title"><a name="d5e102"></a>1.1.3.1. Repeatable entities</h4></div></div></div> |
| |
| <p> |
| An entity can be repeatable, meaning its content can be read more than once. This |
| is only possible with self contained entities (like |
| <code class="classname">ByteArrayEntity</code> or <code class="classname">StringEntity</code>). |
| </p> |
| </div> |
| <div class="section" title="1.1.3.2. Using HTTP entities"><div class="titlepage"><div><div><h4 class="title"><a name="d5e107"></a>1.1.3.2. Using HTTP entities</h4></div></div></div> |
| |
| <p> |
| Since an entity can represent both binary and character content, it has support |
| for character encodings (to support the latter, ie. character content). |
| </p> |
| <p> |
| 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. |
| </p> |
| <p> |
| To read the content from the entity, one can either retrieve the input stream via |
| the <code class="methodname">HttpEntity#getContent()</code> method, which returns an |
| <code class="classname">java.io.InputStream</code>, or one can supply an output stream to |
| the <code class="methodname">HttpEntity#writeTo(OutputStream)</code> method, which will |
| return once all content has been written to the given stream. |
| </p> |
| <p> |
| The <code class="classname">EntityUtils</code> class exposes several static methods to |
| more easily read the content or information from an entity. Instead of reading |
| the <code class="classname">java.io.InputStream</code> directly, one can retrieve the whole |
| content body in a string / byte array by using the methods from this class. |
| </p> |
| <p> |
| When the entity has been received with an incoming message, the methods |
| <code class="methodname">HttpEntity#getContentType()</code> and |
| <code class="methodname">HttpEntity#getContentLength()</code> methods can be used for |
| reading the common metadata such as <code class="literal">Content-Type</code> and |
| <code class="literal">Content-Length</code> headers (if they are available). Since the |
| <code class="literal">Content-Type</code> header can contain a character encoding for text |
| mime-types like <code class="literal">text/plain</code> or <code class="literal">text/html</code>, |
| the <code class="methodname">HttpEntity#getContentEncoding()</code> method is used to |
| read this information. If the headers aren't available, a length of -1 will be |
| returned, and <code class="literal">NULL</code> for the content type. If the |
| <code class="literal">Content-Type</code> header is available, a Header object will be |
| returned. |
| </p> |
| <p> |
| When creating an entity for a outgoing message, this meta data has to be supplied |
| by the creator of the entity. |
| </p> |
| <pre class="programlisting"> |
| 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); |
| </pre> |
| <p>stdout ></p> |
| <pre class="programlisting"> |
| Content-Type: text/plain; charset=UTF-8 |
| 17 |
| UTF-8 |
| important message |
| 17 |
| </pre> |
| </div> |
| <div class="section" title="1.1.3.3. Ensuring release of system resources"><div class="titlepage"><div><div><h4 class="title"><a name="d5e133"></a>1.1.3.3. Ensuring release of system resources</h4></div></div></div> |
| |
| <p> |
| In order to ensure proper release of system resources one must close the content |
| stream associated with the entity. |
| </p> |
| <pre class="programlisting"> |
| HttpResponse response; |
| HttpEntity entity = response.getEntity(); |
| if (entity != null) { |
| InputStream instream = entity.getContent(); |
| try { |
| // do something useful |
| } finally { |
| instream.close(); |
| } |
| } |
| </pre> |
| <p> |
| Please note that <code class="methodname">HttpEntity#writeTo(OutputStream)</code> |
| method is also required to ensure proper release of system resources once the |
| entity has been fully written out. If this method obtains an instance of |
| <code class="classname">java.io.InputStream</code> by calling |
| <code class="methodname">HttpEntity#getContent()</code>, it is also expected to close |
| the stream in a finally clause. |
| </p> |
| <p> |
| When working with streaming entities, one can use the |
| <code class="methodname">EntityUtils#consume(HttpEntity)</code> method to ensure that |
| the entity content has been fully consumed and the underlying stream has been |
| closed. |
| </p> |
| </div> |
| </div> |
| <div class="section" title="1.1.4. Creating entities"><div class="titlepage"><div><div><h3 class="title"><a name="d5e143"></a>1.1.4. Creating entities</h3></div></div></div> |
| |
| <p> |
| There are a few ways to create entities. The following implementations are provided |
| by HttpCore: |
| </p> |
| <div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> |
| <p> |
| <a class="link" href="fundamentals.html#basic-entity" title="1.1.4.1. BasicHttpEntity"> |
| <code class="classname">BasicHttpEntity</code> |
| </a> |
| </p> |
| </li><li class="listitem"> |
| <p> |
| <a class="link" href="fundamentals.html#byte-array-entity" title="1.1.4.2. ByteArrayEntity"> |
| <code class="classname">ByteArrayEntity</code> |
| </a> |
| </p> |
| </li><li class="listitem"> |
| <p> |
| <a class="link" href="fundamentals.html#string-entity" title="1.1.4.3. StringEntity"> |
| <code class="classname">StringEntity</code> |
| </a> |
| </p> |
| </li><li class="listitem"> |
| <p> |
| <a class="link" href="fundamentals.html#input-stream-entity" title="1.1.4.4. InputStreamEntity"> |
| <code class="classname">InputStreamEntity</code> |
| </a> |
| </p> |
| </li><li class="listitem"> |
| <p> |
| <a class="link" href="fundamentals.html#file-entity" title="1.1.4.5. FileEntity"> |
| <code class="classname">FileEntity</code> |
| </a> |
| </p> |
| </li><li class="listitem"> |
| <p> |
| <a class="link" href=""> |
| <code class="classname">EntityTemplate</code> |
| </a> |
| </p> |
| </li><li class="listitem"> |
| <p> |
| <a class="link" href="fundamentals.html#entity-wrapper" title="1.1.4.6. HttpEntityWrapper"> |
| <code class="classname">HttpEntityWrapper</code> |
| </a> |
| </p> |
| </li><li class="listitem"> |
| <p> |
| <a class="link" href="fundamentals.html#buffered-entity" title="1.1.4.7. BufferedHttpEntity"> |
| <code class="classname">BufferedHttpEntity</code> |
| </a> |
| </p> |
| </li></ul></div> |
| <div class="section" title="1.1.4.1. BasicHttpEntity"><div class="titlepage"><div><div><h4 class="title"><a name="basic-entity"></a>1.1.4.1. <code class="classname">BasicHttpEntity</code></h4></div></div></div> |
| |
| <p> |
| This is exactly as the name implies, a basic entity that represents an underlying |
| stream. This is generally used for the entities received from HTTP messages. |
| </p> |
| <p> |
| This entity has an empty constructor. After construction it represents no content, |
| and has a negative content length. |
| </p> |
| <p> |
| One needs to set the content stream, and optionally the length. This can be done |
| with the <code class="methodname">BasicHttpEntity#setContent(InputStream)</code> and |
| <code class="methodname">BasicHttpEntity#setContentLength(long)</code> methods |
| respectively. |
| </p> |
| <pre class="programlisting"> |
| BasicHttpEntity myEntity = new BasicHttpEntity(); |
| myEntity.setContent(someInputStream); |
| myEntity.setContentLength(340); // sets the length to 340 |
| </pre> |
| </div> |
| <div class="section" title="1.1.4.2. ByteArrayEntity"><div class="titlepage"><div><div><h4 class="title"><a name="byte-array-entity"></a>1.1.4.2. <code class="classname">ByteArrayEntity</code></h4></div></div></div> |
| |
| <p> |
| <code class="classname">ByteArrayEntity</code> is a self contained, repeatable entity |
| that obtains its content from a given byte array. This byte array is supplied |
| to the constructor. |
| </p> |
| <pre class="programlisting"> |
| String myData = "Hello world on the other side!!"; |
| ByteArrayEntity myEntity = new ByteArrayEntity(myData.getBytes()); |
| </pre> |
| </div> |
| <div class="section" title="1.1.4.3. StringEntity"><div class="titlepage"><div><div><h4 class="title"><a name="string-entity"></a>1.1.4.3. <code class="classname">StringEntity</code></h4></div></div></div> |
| |
| <p> |
| <code class="classname">StringEntity</code> is a self contained, repeatable entity that |
| obtains its content from a <code class="classname">java.lang.String</code> object. It has |
| three constructors, one simply constructs with a given <code class="classname">java.lang.String |
| </code> object; the second also takes a character encoding for the data in the |
| string; the third allows the mime type to be specified. |
| </p> |
| <pre class="programlisting"> |
| StringBuilder sb = new StringBuilder(); |
| 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 (defaults to ISO-8859-1) |
| HttpEntity myEntity1 = new StringEntity(sb.toString()); |
| |
| // alternatively construct with an encoding (mime type defaults to "text/plain") |
| HttpEntity myEntity2 = new StringEntity(sb.toString(), "UTF-8"); |
| |
| // alternatively construct with an encoding and a mime type |
| HttpEntity myEntity3 = new StringEntity(sb.toString(), "text/html", "UTF-8"); |
| </pre> |
| </div> |
| <div class="section" title="1.1.4.4. InputStreamEntity"><div class="titlepage"><div><div><h4 class="title"><a name="input-stream-entity"></a>1.1.4.4. <code class="classname">InputStreamEntity</code></h4></div></div></div> |
| |
| <p> |
| <code class="classname">InputStreamEntity</code> is a streamed, non-repeatable entity that |
| obtains its content from an input stream. It is constructed by supplying the input |
| stream and the content length. The content length is used to limit the amount of |
| data read from the <code class="classname">java.io.InputStream</code>. 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. |
| </p> |
| <pre class="programlisting"> |
| InputStream instream = getSomeInputStream(); |
| InputStreamEntity myEntity = new InputStreamEntity(instream, 16); |
| </pre> |
| </div> |
| <div class="section" title="1.1.4.5. FileEntity"><div class="titlepage"><div><div><h4 class="title"><a name="file-entity"></a>1.1.4.5. <code class="classname">FileEntity</code></h4></div></div></div> |
| |
| <p> |
| <code class="classname">FileEntity</code> is a self contained, repeatable entity that |
| obtains its content 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 file would require the content type <code class="literal"> |
| application/zip</code>, for XML <code class="literal">application/xml</code>. |
| </p> |
| <pre class="programlisting"> |
| HttpEntity entity = new FileEntity(staticFile, |
| "application/java-archive"); |
| </pre> |
| </div> |
| <div class="section" title="1.1.4.6. HttpEntityWrapper"><div class="titlepage"><div><div><h4 class="title"><a name="entity-wrapper"></a>1.1.4.6. <code class="classname">HttpEntityWrapper</code></h4></div></div></div> |
| |
| <p> |
| This is the base class for creating wrapped entities. The wrapping entity holds |
| a reference to a wrapped entity and delegates all calls to it. Implementations |
| of wrapping entities can derive from this class and need to override only those |
| methods that should not be delegated to the wrapped entity. |
| </p> |
| </div> |
| <div class="section" title="1.1.4.7. BufferedHttpEntity"><div class="titlepage"><div><div><h4 class="title"><a name="buffered-entity"></a>1.1.4.7. <code class="classname">BufferedHttpEntity</code></h4></div></div></div> |
| |
| <p> |
| <code class="classname">BufferedHttpEntity</code> is a subclass of <code class="classname"> |
| HttpEntityWrapper</code>. It is constructed by supplying another entity. It |
| reads the content from the supplied entity, and buffers it in memory. |
| </p> |
| <p> |
| This makes it possible to make a repeatable entity, from a non-repeatable entity. |
| If the supplied entity is already repeatable, calls are simply passed through to the |
| underlying entity. |
| </p> |
| <pre class="programlisting"> |
| myNonRepeatableEntity.setContent(someInputStream); |
| BufferedHttpEntity myBufferedEntity = new BufferedHttpEntity( |
| myNonRepeatableEntity); |
| </pre> |
| </div> |
| </div> |
| </div> |
| <div class="section" title="1.2. Blocking HTTP connections"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d5e229"></a>1.2. Blocking HTTP connections</h2></div></div></div> |
| |
| <p> |
| 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. |
| </p> |
| <p> |
| It is important to bear in mind that HTTP connections are not thread-safe. It is strongly |
| recommended to limit all interactions with HTTP connection objects to one thread. The only |
| method of <code class="interfacename">HttpConnection</code> interface and its sub-interfaces |
| which is safe to invoke from another thread is <code class="methodname"> HttpConnection#shutdown() |
| </code>. |
| </p> |
| <div class="section" title="1.2.1. Working with blocking HTTP connections"><div class="titlepage"><div><div><h3 class="title"><a name="d5e235"></a>1.2.1. Working with blocking HTTP connections</h3></div></div></div> |
| |
| <p> |
| 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 |
| when it involves one or more authenticating or/and tunneling proxies. Instead, blocking |
| HTTP connections can be bound to any arbitrary network socket. |
| </p> |
| <pre class="programlisting"> |
| Socket socket = new Socket(); |
| // Initialize socket |
| BasicHttpParams params = new BasicHttpParams(); |
| DefaultHttpClientConnection conn = new DefaultHttpClientConnection(); |
| conn.bind(socket, params); |
| conn.isOpen(); |
| HttpConnectionMetrics metrics = conn.getMetrics(); |
| metrics.getRequestCount(); |
| metrics.getResponseCount(); |
| metrics.getReceivedBytesCount(); |
| metrics.getSentBytesCount(); |
| </pre> |
| <p> |
| HTTP connection interfaces, both client and server, send and receive messages in two |
| stages. The message head is transmitted first. Depending on properties of the message |
| head it may be followed by a message body. Please note it is very important to always |
| close the underlying content stream in order to signal that the processing of |
| the message is complete. HTTP entities that stream out their content directly from the |
| input stream of the underlying connection must ensure the content of the message body |
| is fully consumed for that connection to be potentially re-usable. |
| </p> |
| <p> |
| Over-simplified process of client side request execution may look like this: |
| </p> |
| <pre class="programlisting"> |
| Socket socket = new Socket(); |
| // Initialize socket |
| HttpParams params = new BasicHttpParams(); |
| DefaultHttpClientConnection conn = new DefaultHttpClientConnection(); |
| conn.bind(socket, params); |
| HttpRequest request = new BasicHttpRequest("GET", "/"); |
| conn.sendRequestHeader(request); |
| HttpResponse response = conn.receiveResponseHeader(); |
| conn.receiveResponseEntity(response); |
| HttpEntity entity = response.getEntity(); |
| if (entity != null) { |
| // Do something useful with the entity and, when done, ensure all |
| // content has been consumed, so that the underlying connection |
| // can be re-used |
| EntityUtils.consume(entity); |
| } |
| </pre> |
| <p> |
| Over-simplified process of server side request handling may look like this: |
| </p> |
| <pre class="programlisting"> |
| Socket socket = new Socket(); |
| // Initialize socket |
| HttpParams params = new BasicHttpParams(); |
| DefaultHttpServerConnection conn = new DefaultHttpServerConnection(); |
| conn.bind(socket, params); |
| HttpRequest request = conn.receiveRequestHeader(); |
| if (request instanceof HttpEntityEnclosingRequest) { |
| conn.receiveRequestEntity((HttpEntityEnclosingRequest) request); |
| HttpEntity entity = ((HttpEntityEnclosingRequest) request) |
| .getEntity(); |
| if (entity != null) { |
| // Do something useful with the entity and, when done, ensure all |
| // content has been consumed, so that the underlying connection |
| // could be re-used |
| EntityUtils.consume(entity); |
| } |
| } |
| HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, |
| 200, "OK"); |
| response.setEntity(new StringEntity("Got it")); |
| conn.sendResponseHeader(response); |
| conn.sendResponseEntity(response); |
| </pre> |
| <p> |
| Please note that one should rarely need to transmit messages using these low level |
| methods and should normally use the appropriate higher level HTTP service implementations instead. |
| </p> |
| </div> |
| <div class="section" title="1.2.2. Content transfer with blocking I/O"><div class="titlepage"><div><div><h3 class="title"><a name="d5e245"></a>1.2.2. Content transfer with blocking I/O</h3></div></div></div> |
| |
| <p> |
| HTTP connections manage the process of the content transfer using the <code class="interfacename"> |
| HttpEntity</code> interface. HTTP connections generate an entity object that |
| encapsulates the content stream of the incoming message. Please note that <code class="methodname"> |
| HttpServerConnection#receiveRequestEntity()</code> and <code class="methodname"> |
| HttpClientConnection#receiveResponseEntity()</code> do not retrieve or buffer any |
| incoming data. They merely inject an appropriate content codec based on the properties |
| of the incoming message. The content can be retrieved by reading from the content input |
| stream of the enclosed entity using <code class="methodname">HttpEntity#getContent()</code>. |
| The incoming data will be decoded automatically, and completely transparently to the data |
| consumer. Likewise, HTTP connections rely on <code class="methodname"> |
| HttpEntity#writeTo(OutputStream)</code> method to generate the content of an |
| outgoing message. If an outgoing messages encloses an entity, the content will be |
| encoded automatically based on the properties of the message. |
| </p> |
| </div> |
| <div class="section" title="1.2.3. Supported content transfer mechanisms"><div class="titlepage"><div><div><h3 class="title"><a name="d5e253"></a>1.2.3. Supported content transfer mechanisms</h3></div></div></div> |
| |
| <p> |
| Default implementations of HTTP connections support three content transfer mechanisms |
| defined by the HTTP/1.1 specification: |
| </p> |
| <div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> |
| <p title="Content-Length delimited:"> |
| <b><code class="literal">Content-Length</code> delimited: </b> |
| |
| The end of the content entity is determined by the value of the <code class="literal"> |
| Content-Length</code> header. Maximum entity length: <code class="methodname"> |
| Long#MAX_VALUE</code>. |
| |
| </p> |
| </li><li class="listitem"> |
| <p title="Identity coding:"> |
| <b>Identity coding: </b> |
| |
| The end of the content entity is demarcated by closing the underlying |
| connection (end of stream condition). For obvious reasons the identity encoding |
| can only be used on the server side. Max entity length: unlimited. |
| |
| </p> |
| </li><li class="listitem"> |
| <p title="Chunk coding:"> |
| <b>Chunk coding: </b> |
| |
| The content is sent in small chunks. Max entity length: unlimited. |
| |
| </p> |
| </li></ul></div> |
| <p> |
| The appropriate content stream class will be created automatically depending on |
| properties of the entity enclosed with the message. |
| </p> |
| </div> |
| <div class="section" title="1.2.4. Terminating HTTP connections"><div class="titlepage"><div><div><h3 class="title"><a name="d5e273"></a>1.2.4. Terminating HTTP connections</h3></div></div></div> |
| |
| <p> |
| HTTP connections can be terminated either gracefully by calling <code class="methodname"> |
| HttpConnection#close()</code> or forcibly by calling <code class="methodname"> |
| HttpConnection#shutdown()</code>. The former tries to flush all buffered data |
| prior to terminating the connection and may block indefinitely. The <code class="methodname"> |
| HttpConnection#close()</code> method is not thread-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 <code class="methodname">HttpConnection#shutdown() |
| </code> method is thread-safe. |
| </p> |
| </div> |
| </div> |
| <div class="section" title="1.3. HTTP exception handling"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d5e280"></a>1.3. HTTP exception handling</h2></div></div></div> |
| |
| <p> |
| All HttpCore components potentially throw two types of exceptions: <code class="classname">IOException |
| </code>in case of an I/O failure such as socket timeout or an socket reset and |
| <code class="classname">HttpException</code> that signals an HTTP failure such as a violation of |
| the HTTP protocol. Usually I/O errors are considered non-fatal and recoverable, whereas |
| HTTP protocol errors are considered fatal and cannot be automatically recovered from. |
| </p> |
| <div class="section" title="1.3.1. Protocol exception"><div class="titlepage"><div><div><h3 class="title"><a name="d5e285"></a>1.3.1. Protocol exception</h3></div></div></div> |
| |
| <p> |
| <code class="classname">ProtocolException</code> signals a fatal HTTP protocol violation that |
| usually results in an immediate termination of the HTTP message processing. |
| </p> |
| </div> |
| </div> |
| <div class="section" title="1.4. HTTP protocol processors"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d5e289"></a>1.4. HTTP protocol processors</h2></div></div></div> |
| |
| <p> |
| HTTP protocol interceptor is a routine that implements a specific aspect of the HTTP |
| protocol. Usually protocol interceptors are expected to act upon one specific header or a |
| group of related headers of the incoming message or populate the outgoing message with one |
| specific header or a group of related headers. Protocol interceptors can also manipulate |
| content entities enclosed with messages; transparent content compression / decompression |
| being a good example. Usually this is accomplished by using the 'Decorator' pattern where |
| a wrapper entity class is used to decorate the original entity. Several protocol |
| interceptors can be combined to form one logical unit. |
| </p> |
| <p> |
| HTTP protocol processor is a collection of protocol interceptors that implements the |
| 'Chain of Responsibility' pattern, where each individual protocol interceptor is expected |
| to work on the particular aspect of the HTTP protocol it is responsible for. |
| </p> |
| <p> |
| Usually the order in which interceptors are executed should not matter as long as they do |
| not depend on a particular state of the execution context. If protocol interceptors have |
| interdependencies and therefore must be executed in a particular order, they should be |
| added to the protocol processor in the same sequence as their expected execution order. |
| </p> |
| <p> |
| Protocol interceptors must be implemented as thread-safe. Similarly to servlets, protocol |
| interceptors should not use instance variables unless access to those variables is |
| synchronized. |
| </p> |
| <div class="section" title="1.4.1. Standard protocol interceptors"><div class="titlepage"><div><div><h3 class="title"><a name="d5e295"></a>1.4.1. Standard protocol interceptors</h3></div></div></div> |
| |
| <p> |
| HttpCore comes with a number of most essential protocol interceptors for client and |
| server HTTP processing. |
| </p> |
| <div class="section" title="1.4.1.1. RequestContent"><div class="titlepage"><div><div><h4 class="title"><a name="d5e298"></a>1.4.1.1. <code class="classname">RequestContent</code></h4></div></div></div> |
| |
| <p> |
| <code class="classname">RequestContent</code> is the most important interceptor for |
| outgoing requests. It is responsible for delimiting content length by adding |
| the <code class="literal">Content-Length</code> or <code class="literal">Transfer-Content</code> headers |
| based on the properties of the enclosed entity and the protocol version. This |
| interceptor is required for correct functioning of client side protocol processors. |
| </p> |
| </div> |
| <div class="section" title="1.4.1.2. ResponseContent"><div class="titlepage"><div><div><h4 class="title"><a name="d5e305"></a>1.4.1.2. <code class="classname">ResponseContent</code></h4></div></div></div> |
| |
| <p> |
| <code class="classname">ResponseContent</code> is the most important interceptor for |
| outgoing responses. It is responsible for delimiting content length by adding |
| <code class="literal">Content-Length</code> or <code class="literal">Transfer-Content</code> headers |
| based on the properties of the enclosed entity and the protocol version. This |
| interceptor is required for correct functioning of server side protocol processors. |
| </p> |
| </div> |
| <div class="section" title="1.4.1.3. RequestConnControl"><div class="titlepage"><div><div><h4 class="title"><a name="d5e312"></a>1.4.1.3. <code class="classname">RequestConnControl</code></h4></div></div></div> |
| |
| <p> |
| <code class="classname">RequestConnControl</code> is responsible for adding the |
| <code class="literal">Connection</code> header to the outgoing requests, which is essential |
| for managing persistence of <code class="literal">HTTP/1.0</code> connections. This |
| interceptor is recommended for client side protocol processors. |
| </p> |
| </div> |
| <div class="section" title="1.4.1.4. ResponseConnControl"><div class="titlepage"><div><div><h4 class="title"><a name="d5e319"></a>1.4.1.4. <code class="classname">ResponseConnControl</code></h4></div></div></div> |
| |
| <p> |
| <code class="classname">ResponseConnControl</code> is responsible for adding |
| the <code class="literal">Connection</code> header to the outgoing responses, which is essential |
| for managing persistence of <code class="literal">HTTP/1.0</code> connections. This |
| interceptor is recommended for server side protocol processors. |
| </p> |
| </div> |
| <div class="section" title="1.4.1.5. RequestDate"><div class="titlepage"><div><div><h4 class="title"><a name="d5e326"></a>1.4.1.5. <code class="classname">RequestDate</code></h4></div></div></div> |
| |
| <p> |
| <code class="classname">RequestDate</code> is responsible for adding the |
| <code class="literal">Date</code> header to the outgoing requests. This interceptor is |
| optional for client side protocol processors. |
| </p> |
| </div> |
| <div class="section" title="1.4.1.6. ResponseDate"><div class="titlepage"><div><div><h4 class="title"><a name="d5e332"></a>1.4.1.6. <code class="classname">ResponseDate</code></h4></div></div></div> |
| |
| <p> |
| <code class="classname">ResponseDate</code> is responsible for adding the |
| <code class="literal">Date</code> header to the outgoing responses. This interceptor is |
| recommended for server side protocol processors. |
| </p> |
| </div> |
| <div class="section" title="1.4.1.7. RequestExpectContinue"><div class="titlepage"><div><div><h4 class="title"><a name="d5e338"></a>1.4.1.7. <code class="classname">RequestExpectContinue</code></h4></div></div></div> |
| |
| <p> |
| <code class="classname">RequestExpectContinue</code> is responsible for enabling the |
| 'expect-continue' handshake by adding the <code class="literal">Expect</code> header. This |
| interceptor is recommended for client side protocol processors. |
| </p> |
| </div> |
| <div class="section" title="1.4.1.8. RequestTargetHost"><div class="titlepage"><div><div><h4 class="title"><a name="d5e344"></a>1.4.1.8. <code class="classname">RequestTargetHost</code></h4></div></div></div> |
| |
| <p> |
| <code class="classname">RequestTargetHost</code> is responsible for adding the |
| <code class="literal">Host</code> header. This interceptor is required for client side |
| protocol processors. |
| </p> |
| </div> |
| <div class="section" title="1.4.1.9. RequestUserAgent"><div class="titlepage"><div><div><h4 class="title"><a name="d5e350"></a>1.4.1.9. <code class="classname">RequestUserAgent</code></h4></div></div></div> |
| |
| <p> |
| <code class="classname">RequestUserAgent</code> is responsible for adding the |
| <code class="literal">User-Agent</code> header. This interceptor is recommended for client |
| side protocol processors. |
| </p> |
| </div> |
| <div class="section" title="1.4.1.10. ResponseServer"><div class="titlepage"><div><div><h4 class="title"><a name="d5e356"></a>1.4.1.10. <code class="classname">ResponseServer</code></h4></div></div></div> |
| |
| <p> |
| <code class="classname">ResponseServer</code> is responsible for adding the |
| <code class="literal">Server</code> header. This interceptor is recommended for server side |
| protocol processors. |
| </p> |
| </div> |
| </div> |
| <div class="section" title="1.4.2. Working with protocol processors"><div class="titlepage"><div><div><h3 class="title"><a name="d5e362"></a>1.4.2. Working with protocol processors</h3></div></div></div> |
| |
| <p> |
| Usually HTTP protocol processors are used to pre-process incoming messages prior to |
| executing application specific processing logic and to post-process outgoing messages. |
| </p> |
| <pre class="programlisting"> |
| BasicHttpProcessor httpproc = new BasicHttpProcessor(); |
| // Required protocol interceptors |
| httpproc.addInterceptor(new RequestContent()); |
| httpproc.addInterceptor(new RequestTargetHost()); |
| // Recommended protocol interceptors |
| httpproc.addInterceptor(new RequestConnControl()); |
| httpproc.addInterceptor(new RequestUserAgent()); |
| httpproc.addInterceptor(new RequestExpectContinue()); |
| |
| HttpContext context = new BasicHttpContext(); |
| |
| HttpRequest request = new BasicHttpRequest("GET", "/"); |
| httpproc.process(request, context); |
| HttpResponse response = null; |
| </pre> |
| <p> |
| Send the request to the target host and get a response. |
| </p> |
| <pre class="programlisting"> |
| httpproc.process(response, context); |
| </pre> |
| <p> |
| Please note the <code class="classname">BasicHttpProcessor</code> class does not synchronize |
| access to its internal structures and therefore may not be thread-safe. |
| </p> |
| </div> |
| <div class="section" title="1.4.3. HTTP context"><div class="titlepage"><div><div><h3 class="title"><a name="d5e370"></a>1.4.3. HTTP context</h3></div></div></div> |
| |
| <p> |
| Protocol interceptors can collaborate by sharing information - such as a processing |
| state - through an HTTP execution context. HTTP context is a structure that can be |
| used to map an attribute name to an attribute value. Internally HTTP context |
| implementations are usually backed by a <code class="classname">HashMap</code>. The primary |
| purpose of the HTTP context is to facilitate information sharing among various |
| logically related components. HTTP context can be used to store a processing state for |
| one message or several consecutive messages. Multiple logically related messages can |
| participate in a logical session if the same context is reused between consecutive |
| messages. |
| </p> |
| <pre class="programlisting"> |
| BasicHttpProcessor httpproc = new BasicHttpProcessor(); |
| httpproc.addInterceptor(new HttpRequestInterceptor() { |
| |
| public void process( |
| HttpRequest request, |
| HttpContext context) throws HttpException, IOException { |
| String id = (String) context.getAttribute("session-id"); |
| if (id != null) { |
| request.addHeader("Session-ID", id); |
| } |
| } |
| |
| |
| }); |
| HttpRequest request = new BasicHttpRequest("GET", "/"); |
| httpproc.process(request, context); |
| </pre> |
| <p> |
| <code class="interfacename">HttpContext</code> instances can be linked together to form a |
| hierarchy. In the simplest form one context can use content of another context to |
| obtain default values of attributes not present in the local context. |
| </p> |
| <pre class="programlisting"> |
| HttpContext parentContext = new BasicHttpContext(); |
| parentContext.setAttribute("param1", Integer.valueOf(1)); |
| parentContext.setAttribute("param2", Integer.valueOf(2)); |
| |
| HttpContext localContext = new BasicHttpContext(); |
| localContext.setAttribute("param2", Integer.valueOf(0)); |
| localContext.setAttribute("param3", Integer.valueOf(3)); |
| HttpContext stack = new DefaultedHttpContext(localContext, |
| parentContext); |
| |
| System.out.println(stack.getAttribute("param1")); |
| System.out.println(stack.getAttribute("param2")); |
| System.out.println(stack.getAttribute("param3")); |
| System.out.println(stack.getAttribute("param4")); |
| </pre> |
| <p>stdout ></p> |
| <pre class="programlisting"> |
| 1 |
| 0 |
| 3 |
| null |
| </pre> |
| </div> |
| </div> |
| <div class="section" title="1.5. HTTP parameters"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d5e380"></a>1.5. HTTP parameters</h2></div></div></div> |
| |
| <p> |
| <code class="interfacename">HttpParams</code> interface represents a collection of immutable |
| values that define a runtime behavior of a component. In many ways <code class="interfacename">HttpParams |
| </code> is similar to <code class="interfacename">HttpContext</code>. The main |
| distinction between the two lies in their use at runtime. Both interfaces represent a |
| collection of objects that are organized as a map of textual names to object values, but |
| serve distinct purposes: |
| </p> |
| <div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> |
| <p> |
| <code class="interfacename">HttpParams</code> is intended to contain simple objects: |
| integers, doubles, strings, collections and objects that remain immutable at |
| runtime. <code class="interfacename">HttpParams</code> is expected to be used in the |
| 'write once - read many' mode. <code class="interfacename">HttpContext</code> is |
| intended to contain complex objects that are very likely to mutate in the course of |
| HTTP message processing. |
| </p> |
| </li><li class="listitem"> |
| <p> |
| The purpose of <code class="interfacename">HttpParams</code> is to define a behavior of |
| other components. Usually each complex component has its own <code class="interfacename"> |
| HttpParams</code> object. The purpose of <code class="interfacename">HttpContext |
| </code> is to represent an execution state of an HTTP process. Usually |
| the same execution context is shared among many collaborating objects. |
| </p> |
| </li></ul></div> |
| <p> |
| <code class="interfacename">HttpParams</code>, like <code class="interfacename">HttpContext</code> |
| can be linked together to form a hierarchy. In the simplest form one set of parameters can |
| use content of another one to obtain default values of parameters not present in the local |
| set. |
| </p> |
| <pre class="programlisting"> |
| HttpParams parentParams = new BasicHttpParams(); |
| parentParams.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, |
| HttpVersion.HTTP_1_0); |
| parentParams.setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET, |
| "UTF-8"); |
| |
| HttpParams localParams = new BasicHttpParams(); |
| localParams.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, |
| HttpVersion.HTTP_1_1); |
| localParams.setParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, |
| Boolean.FALSE); |
| HttpParams stack = new DefaultedHttpParams(localParams, |
| parentParams); |
| |
| System.out.println(stack.getParameter( |
| CoreProtocolPNames.PROTOCOL_VERSION)); |
| System.out.println(stack.getParameter( |
| CoreProtocolPNames.HTTP_CONTENT_CHARSET)); |
| System.out.println(stack.getParameter( |
| CoreProtocolPNames.USE_EXPECT_CONTINUE)); |
| System.out.println(stack.getParameter( |
| CoreProtocolPNames.USER_AGENT)); |
| </pre> |
| <p>stdout ></p> |
| <pre class="programlisting"> |
| HTTP/1.1 |
| UTF-8 |
| false |
| null |
| </pre> |
| <p> |
| Please note the <code class="classname">BasicHttpParams</code> class does not synchronize access to |
| its internal structures and therefore may not be thread-safe. |
| </p> |
| <div class="section" title="1.5.1. HTTP parameter beans"><div class="titlepage"><div><div><h3 class="title"><a name="d5e405"></a>1.5.1. HTTP parameter beans</h3></div></div></div> |
| |
| <p> |
| <code class="interfacename">HttpParams</code> interface allows for a great deal of |
| flexibility in handling configuration of components. Most importantly, new parameters |
| can be introduced without affecting binary compatibility with older versions. However, |
| <code class="interfacename">HttpParams</code> also has a certain disadvantage compared to |
| regular Java beans: <code class="interfacename">HttpParams</code> cannot be assembled using |
| a DI framework. To mitigate the limitation, HttpCore includes a number of bean classes |
| that can be used in order to initialize <code class="interfacename">HttpParams</code> objects |
| using standard Java bean conventions. |
| </p> |
| <pre class="programlisting"> |
| HttpParams params = new BasicHttpParams(); |
| HttpProtocolParamBean paramsBean = new HttpProtocolParamBean(params); |
| paramsBean.setVersion(HttpVersion.HTTP_1_1); |
| paramsBean.setContentCharset("UTF-8"); |
| paramsBean.setUseExpectContinue(true); |
| |
| System.out.println(params.getParameter( |
| CoreProtocolPNames.PROTOCOL_VERSION)); |
| System.out.println(params.getParameter( |
| CoreProtocolPNames.HTTP_CONTENT_CHARSET)); |
| System.out.println(params.getParameter( |
| CoreProtocolPNames.USE_EXPECT_CONTINUE)); |
| System.out.println(params.getParameter( |
| CoreProtocolPNames.USER_AGENT)); |
| </pre> |
| <p>stdout ></p> |
| <pre class="programlisting"> |
| HTTP/1.1 |
| UTF-8 |
| false |
| null |
| </pre> |
| </div> |
| </div> |
| <div class="section" title="1.6. Blocking HTTP protocol handlers"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d5e415"></a>1.6. Blocking HTTP protocol handlers</h2></div></div></div> |
| |
| <div class="section" title="1.6.1. HTTP service"><div class="titlepage"><div><div><h3 class="title"><a name="d5e417"></a>1.6.1. HTTP service</h3></div></div></div> |
| |
| <p> |
| <code class="classname">HttpService</code> is a server side HTTP protocol handler based on the |
| blocking I/O model that implements the essential requirements of the HTTP protocol for |
| the server side message processing as described by RFC 2616. |
| </p> |
| <p> |
| <code class="classname">HttpService</code> relies on <code class="interfacename">HttpProcessor |
| </code> instance to generate mandatory protocol headers for all outgoing |
| messages and apply common, cross-cutting message transformations to all incoming and |
| outgoing messages, whereas HTTP request handlers are expected to take care of |
| application specific content generation and processing. |
| </p> |
| <pre class="programlisting"> |
| HttpParams params; |
| // Initialize HTTP parameters |
| HttpProcessor httpproc; |
| // Initialize HTTP processor |
| |
| HttpService httpService = new HttpService( |
| httpproc, |
| new DefaultConnectionReuseStrategy(), |
| new DefaultHttpResponseFactory()); |
| httpService.setParams(params); |
| </pre> |
| <div class="section" title="1.6.1.1. HTTP request handlers"><div class="titlepage"><div><div><h4 class="title"><a name="d5e425"></a>1.6.1.1. HTTP request handlers</h4></div></div></div> |
| |
| <p> |
| The <code class="interfacename">HttpRequestHandler</code> interface represents a |
| routine for processing of a specific group of HTTP requests. <code class="classname">HttpService |
| </code> 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 sent back to the client in response to the given |
| request. |
| </p> |
| <pre class="programlisting"> |
| HttpRequestHandler myRequestHandler = new HttpRequestHandler() { |
| |
| public void handle( |
| HttpRequest request, |
| HttpResponse response, |
| HttpContext context) throws HttpException, IOException { |
| response.setStatusCode(HttpStatus.SC_OK); |
| response.addHeader("Content-Type", "text/plain"); |
| response.setEntity( |
| new StringEntity("some important message")); |
| } |
| |
| }; |
| </pre> |
| </div> |
| <div class="section" title="1.6.1.2. Request handler resolver"><div class="titlepage"><div><div><h4 class="title"><a name="d5e431"></a>1.6.1.2. Request handler resolver</h4></div></div></div> |
| |
| <p> |
| HTTP request handlers are usually managed by a <code class="interfacename"> |
| HttpRequestHandlerResolver</code> 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: <code class="classname"> |
| HttpRequestHandlerRegistry</code> supports only three formats: |
| <code class="literal">*</code>, <code class="literal"><uri>*</code> and |
| <code class="literal">*<uri></code>. |
| </p> |
| <pre class="programlisting"> |
| HttpService httpService; |
| // Initialize HTTP service |
| |
| HttpRequestHandlerRegistry handlerResolver = |
| new HttpRequestHandlerRegistry(); |
| handlerReqistry.register("/service/*", myRequestHandler1); |
| handlerReqistry.register("*.do", myRequestHandler2); |
| handlerReqistry.register("*", myRequestHandler3); |
| |
| // Inject handler resolver |
| httpService.setHandlerResolver(handlerResolver); |
| </pre> |
| <p> |
| Users are encouraged to provide more sophisticated implementations of |
| <code class="interfacename">HttpRequestHandlerResolver</code> - for instance, based on |
| regular expressions. |
| </p> |
| </div> |
| <div class="section" title="1.6.1.3. Using HTTP service to handle requests"><div class="titlepage"><div><div><h4 class="title"><a name="d5e442"></a>1.6.1.3. Using HTTP service to handle requests</h4></div></div></div> |
| |
| <p> |
| When fully initialized and configured, the <code class="classname">HttpService</code> can |
| be used to execute and handle requests for active HTTP connections. The |
| <code class="methodname">HttpService#handleRequest()</code> method reads an incoming |
| request, generates a response and sends it back to the client. This method can be |
| executed in a loop to handle multiple requests on a persistent connection. The |
| <code class="methodname">HttpService#handleRequest()</code> method is safe to execute from |
| multiple threads. This allows processing of requests on several connections |
| simultaneously, as long as all the protocol interceptors and requests handlers used |
| by the <code class="classname">HttpService</code> are thread-safe. |
| </p> |
| <pre class="programlisting"> |
| HttpService httpService; |
| // Initialize HTTP service |
| HttpServerConnection conn; |
| // Initialize connection |
| HttpContext context; |
| // Initialize HTTP context |
| |
| boolean active = true; |
| try { |
| while (active && conn.isOpen()) { |
| httpService.handleRequest(conn, context); |
| } |
| } finally { |
| conn.shutdown(); |
| } |
| </pre> |
| </div> |
| </div> |
| <div class="section" title="1.6.2. HTTP request executor"><div class="titlepage"><div><div><h3 class="title"><a name="d5e450"></a>1.6.2. HTTP request executor</h3></div></div></div> |
| |
| <p> |
| <code class="classname">HttpRequestExecutor</code> is a client side HTTP protocol handler based |
| on the blocking I/O model that implements the essential requirements of the HTTP |
| protocol for the client side message processing, as described by RFC 2616. |
| The <code class="classname">HttpRequestExecutor</code> relies on the <code class="interfacename">HttpProcessor |
| </code> instance to generate mandatory protocol headers for all outgoing |
| messages and apply common, cross-cutting message transformations to all incoming and |
| outgoing messages. Application specific processing can be implemented outside |
| <code class="classname">HttpRequestExecutor</code> once the request has been executed and a |
| response has been received. |
| </p> |
| <pre class="programlisting"> |
| HttpClientConnection conn; |
| // Create connection |
| HttpParams params; |
| // Initialize HTTP parameters |
| HttpProcessor httpproc; |
| // Initialize HTTP processor |
| HttpContext context; |
| // Initialize HTTP context |
| |
| HttpRequestExecutor httpexecutor = new HttpRequestExecutor(); |
| |
| BasicHttpRequest request = new BasicHttpRequest("GET", "/"); |
| request.setParams(params); |
| httpexecutor.preProcess(request, httpproc, context); |
| HttpResponse response = httpexecutor.execute( |
| request, conn, context); |
| response.setParams(params); |
| httpexecutor.postProcess(response, httpproc, context); |
| |
| HttpEntity entity = response.getEntity(); |
| EntityUtils.consume(entity); |
| </pre> |
| <p> |
| Methods of <code class="classname">HttpRequestExecutor</code> are safe to execute from multiple |
| threads. This allows execution of requests on several connections simultaneously, as |
| long as all the protocol interceptors used by the <code class="classname">HttpRequestExecutor |
| </code> are thread-safe. |
| </p> |
| </div> |
| <div class="section" title="1.6.3. Connection persistence / re-use"><div class="titlepage"><div><div><h3 class="title"><a name="d5e461"></a>1.6.3. Connection persistence / re-use</h3></div></div></div> |
| |
| <p> |
| The <code class="interfacename">ConnectionReuseStrategy</code> interface is intended to |
| determine whether the underlying connection can be re-used for processing of further |
| messages after the transmission of the current message has been completed. The default |
| connection re-use strategy attempts to keep connections alive whenever possible. |
| Firstly, it examines the version of the HTTP protocol used to transmit the message. |
| <code class="literal">HTTP/1.1</code> connections are persistent by default, while <code class="literal"> |
| HTTP/1.0</code> connections are not. Secondly, it examines the value of the |
| <code class="literal">Connection</code> header. The peer can indicate whether it intends to |
| re-use the connection on the opposite side by sending <code class="literal">Keep-Alive</code> or |
| <code class="literal">Close</code> values in the <code class="literal">Connection</code> header. Thirdly, |
| the strategy makes the decision whether the connection is safe to re-use based on the |
| properties of the enclosed entity, if available. |
| </p> |
| </div> |
| </div> |
| </div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="preface.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="nio.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Preface </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 2. NIO extensions</td></tr></table></div></body></html> |