You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2012/02/04 17:30:30 UTC

svn commit: r1240534 - in /httpcomponents/httpclient/trunk/src/docbkx: authentication.xml connmgmt.xml fluent.xml fundamentals.xml index.xml

Author: olegk
Date: Sat Feb  4 16:30:30 2012
New Revision: 1240534

URL: http://svn.apache.org/viewvc?rev=1240534&view=rev
Log:
Updated HttpClient tutorial with 4.2 API changes

Added:
    httpcomponents/httpclient/trunk/src/docbkx/fluent.xml   (with props)
Modified:
    httpcomponents/httpclient/trunk/src/docbkx/authentication.xml
    httpcomponents/httpclient/trunk/src/docbkx/connmgmt.xml
    httpcomponents/httpclient/trunk/src/docbkx/fundamentals.xml
    httpcomponents/httpclient/trunk/src/docbkx/index.xml

Modified: httpcomponents/httpclient/trunk/src/docbkx/authentication.xml
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/src/docbkx/authentication.xml?rev=1240534&r1=1240533&r2=1240534&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/src/docbkx/authentication.xml (original)
+++ httpcomponents/httpclient/trunk/src/docbkx/authentication.xml Sat Feb  4 16:30:30 2012
@@ -113,7 +113,7 @@ pwd
             </listitem>
             <listitem>
                 <formalpara>
-                    <title>SPNEGO/Kerberos:</title>
+                    <title>SPNEGO:</title>
                     <para><literal>SPNEGO</literal> (<emphasis>S</emphasis>imple and
                             <emphasis>P</emphasis>rotected <literal>GSSAPI</literal>
                         <emphasis>Nego</emphasis>tiation Mechanism) is a <literal>GSSAPI</literal>
@@ -124,6 +124,12 @@ pwd
                         At present HttpClient only supports the Kerberos sub-mechanism. </para>
                 </formalpara>
             </listitem>
+            <listitem>
+                <formalpara>
+                    <title>Kerberos:</title>
+                    <para>Kerberos authentication implementation. </para>
+                </formalpara>
+            </listitem>
         </itemizedlist>
     </section>
     <section>
@@ -209,7 +215,13 @@ httpclient.getParams().setParameter(Auth
             <listitem>
                 <formalpara>
                     <title>AuthPolicy.SPNEGO:</title>
-                    <para>SPNEGO/Kerberos authentication</para>
+                    <para>SPNEGO authentication</para>
+                </formalpara>
+            </listitem>
+            <listitem>
+                <formalpara>
+                    <title>AuthPolicy.KERBEROS:</title>
+                    <para>Kerberos authentication</para>
                 </formalpara>
             </listitem>
         </itemizedlist>
@@ -327,12 +339,12 @@ HttpResponse response = httpclient.execu
 
 AuthState proxyAuthState = (AuthState) localContext.getAttribute(
     ClientContext.PROXY_AUTH_STATE);
-System.out.println("Proxy auth scope: " + proxyAuthState.getAuthScope());
+System.out.println("Proxy auth state: " + proxyAuthState.getState());
 System.out.println("Proxy auth scheme: " + proxyAuthState.getAuthScheme());
 System.out.println("Proxy auth credentials: " + proxyAuthState.getCredentials());
 AuthState targetAuthState = (AuthState) localContext.getAttribute(
     ClientContext.TARGET_AUTH_STATE);
-System.out.println("Target auth scope: " + targetAuthState.getAuthScope());
+System.out.println("Target auth state: " + targetAuthState.getState());
 System.out.println("Target auth scheme: " + targetAuthState.getAuthScheme());
 System.out.println("Target auth credentials: " + targetAuthState.getCredentials());
 ]]></programlisting>
@@ -490,7 +502,7 @@ EntityUtils.consume(entity2);
                 supports <literal>SPNEGO</literal> authentication more completely.</para>
             <para>The Sun JRE provides the supporting classes to do nearly all the Kerberos and
                     <literal>SPNEGO</literal> token handling. This means that a lot of the setup is
-                for the GSS classes. The <classname>NegotiateScheme</classname> is a simple class to
+                for the GSS classes. The <classname>SPNegoScheme</classname> is a simple class to
                 handle marshalling the tokens and reading and writing the correct headers.</para>
             <para>The best way to start is to grab the <literal>KerberosHttpClient.java</literal>
                 file in examples and try and get it to work. There are a lot of issues that can
@@ -583,40 +595,6 @@ Value: 0x01
 ]]>
             </programlisting>
         </section>
-        <section>
-            <title>Customizing <literal>SPNEGO</literal> authentication scheme</title>
-            <para>In order to customize <literal>SPNEGO</literal> support a new instance of
-                the <classname>NegotiateSchemeFactory</classname> class must be created and
-                registered with the authentication scheme registry of HttpClient. </para>
-            <programlisting><![CDATA[
-DefaultHttpClient httpclient = new DefaultHttpClient();
-NegotiateSchemeFactory nsf = new NegotiateSchemeFactory();
-httpclient.getAuthSchemes().register(AuthPolicy.SPNEGO, nsf);
-]]>
-            </programlisting>
-            <para>There are several options that can be used to customize the behaviour of
-                    <classname>NegotiateSchemeFactory</classname>. </para>
-            <section>
-                <title>Strip port</title>
-                <para>Strips the port off service names e.g.
-                        <literal>HTTP/webserver.ad.example.net:8080</literal> ->
-                        <literal>HTTP/webserver.ad.example.net</literal></para>
-                <para>Found it useful when authenticating against JBoss Negotiation.</para>
-            </section>
-            <section>
-                <title>Custom <literal>SPNEGO</literal> token generator</title>
-                <para>Use this method to inject a custom
-                        <interfacename>SpnegoTokenGenerator</interfacename> class to do the Kerberos
-                    to <literal>SPNEGO</literal> token wrapping.
-                    The <classname>BouncySpnegoTokenGenerator</classname> implementation is provided
-                    as an unsupported contribution from the contrib package. This requires the
-                    BouncyCastle libraries <ulink url="http://www.bouncycastle.org/java.html"
-                        >"http://www.bouncycastle.org/java.html"</ulink>. Found especially useful 
-                    when using Java 1.5, which is known to provide only a limited support for 
-                    <literal>SPNEGO</literal> authentication.    
-                </para>
-            </section>
-        </section>
     </section>
 
 </chapter>

Modified: httpcomponents/httpclient/trunk/src/docbkx/connmgmt.xml
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/src/docbkx/connmgmt.xml?rev=1240534&r1=1240533&r2=1240534&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/src/docbkx/connmgmt.xml (original)
+++ httpcomponents/httpclient/trunk/src/docbkx/connmgmt.xml Sat Feb  4 16:30:30 2012
@@ -270,37 +270,14 @@ sf.connectSocket(socket, address, null, 
                     <interfacename>javax.net.ssl.SSLContext</interfacename> as a parameter and use
                 it to create custom configured SSL connections.</para>
             <programlisting><![CDATA[
-TrustManager easyTrustManager = new X509TrustManager() {
-
-    @Override
-    public void checkClientTrusted(
-            X509Certificate[] chain,
-            String authType) throws CertificateException {
-        // Oh, I am easy!
-    }
-
-    @Override
-    public void checkServerTrusted(
-            X509Certificate[] chain,
-            String authType) throws CertificateException {
-        // Oh, I am easy!
-    }
-
-    @Override
-    public X509Certificate[] getAcceptedIssuers() {
-        return null;
-    }
-    
-};
-
+HttpParams params = new BasicHttpParams();
 SSLContext sslcontext = SSLContext.getInstance("TLS");
-sslcontext.init(null, new TrustManager[] { easyTrustManager }, null);
+sslcontext.init(null, null, null);
 
 SSLSocketFactory sf = new SSLSocketFactory(sslcontext); 
-SSLSocket socket = (SSLSocket) sf.createSocket();
+SSLSocket socket = (SSLSocket) sf.createSocket(params);
 socket.setEnabledCipherSuites(new String[] { "SSL_RSA_WITH_RC4_128_MD5" });
 
-HttpParams params = new BasicHttpParams();
 params.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 1000L);
 InetSocketAddress address = new InetSocketAddress("locahost", 443);
 sf.connectSocket(socket, address, null, params);
@@ -485,7 +462,7 @@ httpclient.setRoutePlanner(new HttpRoute
 Scheme http = new Scheme("http", 80, PlainSocketFactory.getSocketFactory());
 SchemeRegistry sr = new SchemeRegistry();
 sr.register(http);
-ClientConnectionManager connMrg = new SingleClientConnManager(sr);
+ClientConnectionManager connMrg = new BasicClientConnectionManager(sr);
 
 // Request new connection. This can be a long process
 ClientConnectionRequest connRequest = connMrg.requestConnection(
@@ -539,27 +516,27 @@ try {
         </section>
         <section>
             <title>Simple connection manager</title>
-            <para><classname>SingleClientConnManager</classname> is a simple connection manager that
-                maintains only one connection at a time. Even though this class is thread-safe it
-                ought to be used by one execution thread only.
-                    <classname>SingleClientConnManager</classname> will make an effort to reuse the
-                connection for subsequent requests with the same route. It will, however, close the
-                existing connection and re-open it for the given route, if the route of the persistent
-                connection does not match that of the connection request. If the connection has been
-                already been allocated, then
-                    <exceptionname>java.lang.IllegalStateException</exceptionname> is thrown.</para>
-            <para><classname>SingleClientConnManager</classname> is used by HttpClient per
+            <para><classname>BasicClientConnectionManager</classname> is a simple connection manager
+                that maintains only one connection at a time. Even though this class is thread-safe 
+                it ought to be used by one execution thread only.
+                <classname>BasicClientConnectionManager</classname> will make an effort to reuse 
+                the connection for subsequent requests with the same route. It will, however, close 
+                the existing connection and re-open it for the given route, if the route of the 
+                persistent connection does not match that of the connection request. 
+                If the connection has been already been allocated, then <exceptionname>
+                java.lang.IllegalStateException</exceptionname> is thrown.</para>
+            <para><classname>BasicClientConnectionManager</classname> is used by HttpClient per
                 default.</para>
         </section>
         <section>
             <title>Pooling connection manager</title>
-            <para><classname>ThreadSafeClientConnManager</classname> is a more complex
+            <para><classname>PoolingClientConnectionManager</classname> is a more complex
                 implementation that manages a pool of client connections and is able to service
                 connection requests from multiple execution threads. Connections are pooled on a per
                 route basis. A request for a route for which the manager already has a persistent
                 connection available in the pool will be serviced by leasing a connection from
                 the pool rather than creating a brand new connection.</para>
-            <para><classname>ThreadSafeClientConnManager</classname> maintains a maximum limit of
+            <para><classname>PoolingClientConnectionManager</classname> maintains a maximum limit of
                 connections on a per route basis and in total. Per default this implementation will
                 create no more than 2 concurrent connections per given route and no more 20
                 connections in total. For many real-world applications these limits may prove too
@@ -573,14 +550,14 @@ schemeRegistry.register(
 schemeRegistry.register(
          new Scheme("https", 443, SSLSocketFactory.getSocketFactory()));
 
-ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(schemeRegistry);
+PoolingClientConnectionManager cm = new PoolingClientConnectionManager(schemeRegistry);
 // Increase max total connection to 200
-cm.setMaxTotalConnections(200);
+cm.setMaxTotal(200);
 // Increase default max connection per route to 20
 cm.setDefaultMaxPerRoute(20);
 // Increase max connections for localhost:80 to 50
 HttpHost localhost = new HttpHost("locahost", 80);
-cm.setMaxForRoute(new HttpRoute(localhost), 50);
+cm.setMaxPerRoute(new HttpRoute(localhost), 50);
  
 HttpClient httpClient = new DefaultHttpClient(cm);
 ]]></programlisting>
@@ -604,22 +581,23 @@ httpclient.getConnectionManager().shutdo
     </section>
     <section>
         <title>Multithreaded request execution</title>
-        <para>When equipped with a pooling connection manager such as ThreadSafeClientConnManager,
-            HttpClient can be used to execute multiple requests simultaneously using multiple
-            threads of execution.</para>
-        <para>The <classname>ThreadSafeClientConnManager</classname> will allocate connections based on
-            its configuration. If all connections for a given route have already been leased, a
-            request for a connection will block until a connection is released back to the pool. One
-            can ensure the connection manager does not block indefinitely in the connection request
-            operation by setting <literal>'http.conn-manager.timeout'</literal> to a positive value.
-            If the connection request cannot be serviced within the given time period
-                <exceptionname>ConnectionPoolTimeoutException</exceptionname> will be thrown.</para>
+        <para>When equipped with a pooling connection manager such as <classname>
+            PoolingClientConnectionManager</classname>, HttpClient can be used to execute multiple 
+            requests simultaneously using multiple threads of execution.</para>
+        <para>The <classname>PoolingClientConnectionManager</classname> will allocate connections 
+            based on its configuration. If all connections for a given route have already been 
+            leased, a request for a connection will block until a connection is released back to 
+            the pool. One can ensure the connection manager does not block indefinitely in the 
+            connection request operation by setting <literal>'http.conn-manager.timeout'</literal> 
+            to a positive value. If the connection request cannot be serviced within the given time 
+            period <exceptionname>ConnectionPoolTimeoutException</exceptionname> will be thrown.
+            </para>
         <programlisting><![CDATA[
 SchemeRegistry schemeRegistry = new SchemeRegistry();
 schemeRegistry.register(
         new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));
 
-ClientConnectionManager cm = new ThreadSafeClientConnManager(schemeRegistry);
+ClientConnectionManager cm = new PoolingClientConnectionManager(schemeRegistry);
 HttpClient httpClient = new DefaultHttpClient(cm);
 
 // URIs to perform GETs on

Added: httpcomponents/httpclient/trunk/src/docbkx/fluent.xml
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/src/docbkx/fluent.xml?rev=1240534&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/src/docbkx/fluent.xml (added)
+++ httpcomponents/httpclient/trunk/src/docbkx/fluent.xml Sat Feb  4 16:30:30 2012
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE preface PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
+                 "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
+<!-- 
+   ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+   ====================================================================
+
+-->
+<chapter id="fluent">
+  <title>Fluent API</title>
+  <section>
+    <title>Easy to use facade API</title>
+    <para>
+    As of version of 4.2 HttpClient comes with an easy to use facade API based on the concept 
+    of a fluent interface. Fluent facade API exposes only the most fundamental functions of 
+    HttpClient and is intended for simple use cases that do not require the full flexibility of 
+    HttpClient. For instance, fluent facade API relieves the users from having to deal with 
+    connection management and resource deallocation.  
+    </para>
+    <para>Here are several examples of HTTP requests executed through the HC fluent API</para>
+    <programlisting><![CDATA[
+// Execute a GET with timeout settings and return response content as String.
+Request.Get("http://somehost/")
+        .connectTimeout(1000)
+        .socketTimeout(1000)
+        .execute().returnContent().asString();
+]]>
+    </programlisting>
+    <programlisting><![CDATA[
+// Execute a POST with the 'expect-continue' handshake, using HTTP/1.1,
+// containing a request body as String and return response content as byte array.
+Request.Post("http://somehost/do-stuff")
+        .useExpectContinue()
+        .version(HttpVersion.HTTP_1_1)
+        .bodyString("Important stuff", ContentType.DEFAULT_TEXT)
+        .execute().returnContent().asBytes();
+]]>
+    </programlisting>
+    <programlisting><![CDATA[
+// Execute a POST with a custom header through the proxy containing a request body
+// as an HTML form and save the result to the file
+Request.Post("http://somehost/some-form")
+        .addHeader("X-Custom-header", "stuff")
+        .viaProxy(new HttpHost("myproxy", 8080))
+        .bodyForm(Form.form().add("username", "vip").add("password", "secret").build())
+        .execute().saveContent(new File("result.dump"));
+]]>
+    </programlisting>
+    <para>One can also use <classname>Executor</classname> directly in order to execute requests in 
+    a specific security context whereby authentication details are cached and re-used for 
+    subsequent requests.
+    </para>
+    <programlisting><![CDATA[
+Executor executor = Executor.newInstance()
+        .auth(new HttpHost("somehost"), "username", "password")
+        .auth(new HttpHost("myproxy", 8080), "username", "password")
+        .authPreemptive(new HttpHost("myproxy", 8080));
+
+executor.execute(Request.Get("http://somehost/"))
+        .returnContent().asString();
+
+executor.execute(Request.Post("http://somehost/do-stuff")
+        .useExpectContinue()
+        .bodyString("Important stuff", ContentType.DEFAULT_TEXT))
+        .returnContent().asString();
+]]>
+    </programlisting>
+    <section>
+      <title>Response handling</title>
+      <para>The fluent facade API generally relieves the users from having to deal with 
+      connection management and resource deallocation. In most cases, though, this comes at 
+      a price of having to buffer content of response messages in memory. It is highly 
+      recommended to use <interfacename>ResponseHandler</interfacename> for HTTP response 
+      processing in order to avoid having to buffer content in memory.</para>
+      <programlisting><![CDATA[
+Document result = Request.Get("http://somehost/content")
+        .execute().handleResponse(new ResponseHandler<Document>() {
+
+    public Document handleResponse(final HttpResponse response) throws IOException {
+        StatusLine statusLine = response.getStatusLine();
+        HttpEntity entity = response.getEntity();
+        if (statusLine.getStatusCode() >= 300) {
+            throw new HttpResponseException(
+                    statusLine.getStatusCode(),
+                    statusLine.getReasonPhrase());
+        }
+        if (entity == null) {
+            throw new ClientProtocolException("Response contains no content");
+        }
+        DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
+        try {
+            DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
+            ContentType contentType = ContentType.getOrDefault(entity);
+            if (!contentType.equals(ContentType.APPLICATION_XML)) {
+                throw new ClientProtocolException("Unexpected content type:" + contentType);
+            }
+            String charset = contentType.getCharset();
+            if (charset == null) {
+                charset = HTTP.DEFAULT_CONTENT_CHARSET;
+            }
+            return docBuilder.parse(entity.getContent(), charset);
+        } catch (ParserConfigurationException ex) {
+            throw new IllegalStateException(ex);
+        } catch (SAXException ex) {
+            throw new ClientProtocolException("Malformed XML document", ex);
+        }
+    }
+
+    });
+]]>
+      </programlisting>
+    </section>
+    <section>
+      <title>Asynchronous execution</title>
+      <para>The fluent facade API can be used to execute multiple requests asynchronously using 
+      background threads.
+      </para> 
+      <programlisting><![CDATA[
+ExecutorService threadpool = Executors.newFixedThreadPool(2);
+Async async = Async.newInstance().use(threadpool);
+
+Request[] requests = new Request[] {
+        Request.Get("http://www.google.com/"),
+        Request.Get("http://www.yahoo.com/"),
+        Request.Get("http://www.apache.com/"),
+        Request.Get("http://www.apple.com/")
+};
+
+Queue<Future<Content>> queue = new LinkedList<Future<Content>>();
+for (final Request request: requests) {
+    Future<Content> future = async.execute(request, new FutureCallback<Content>() {
+        
+        public void failed(final Exception ex) {
+            System.out.println(ex.getMessage() + ": " + request);
+        }
+        
+        public void completed(final Content content) {
+            System.out.println("Request completed: " + request);
+        }
+        
+        public void cancelled() {
+        }
+        
+    });
+    queue.add(future);
+}
+
+// Process the queue
+]]>
+      </programlisting>
+    </section>
+  </section>
+</chapter>

Propchange: httpcomponents/httpclient/trunk/src/docbkx/fluent.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpclient/trunk/src/docbkx/fluent.xml
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpclient/trunk/src/docbkx/fluent.xml
------------------------------------------------------------------------------
    svn:mime-type = text/xml

Modified: httpcomponents/httpclient/trunk/src/docbkx/fundamentals.xml
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/src/docbkx/fundamentals.xml?rev=1240534&r1=1240533&r2=1240534&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/src/docbkx/fundamentals.xml (original)
+++ httpcomponents/httpclient/trunk/src/docbkx/fundamentals.xml Sat Feb  4 16:30:30 2012
@@ -40,9 +40,10 @@ HttpResponse response = httpclient.execu
 HttpEntity entity = response.getEntity();
 if (entity != null) {
     InputStream instream = entity.getContent();
-    int l;
-    byte[] tmp = new byte[2048];
-    while ((l = instream.read(tmp)) != -1) {
+    try {
+        // do something useful
+    } finally {
+        instream.close();
     }
 }
 ]]></programlisting>
@@ -65,28 +66,16 @@ if (entity != null) {
 HttpGet httpget = new HttpGet(
      "http://www.google.com/search?hl=en&q=httpclient&btnG=Google+Search&aq=f&oq=");
 ]]></programlisting>
-            <para>HttpClient provides a number of utility methods to simplify creation and
-                modification of request URIs.</para>
-            <para>URI can be assembled programmatically:</para>
-            <programlisting><![CDATA[
-URI uri = URIUtils.createURI("http", "www.google.com", -1, "/search", 
-    "q=httpclient&btnG=Google+Search&aq=f&oq=", null);
-HttpGet httpget = new HttpGet(uri);
-System.out.println(httpget.getURI());
-]]></programlisting>
-            <para>stdout &gt;</para>
-            <programlisting><![CDATA[
-http://www.google.com/search?q=httpclient&btnG=Google+Search&aq=f&oq=
-]]></programlisting>
-            <para>Query string can also be generated from individual parameters:</para>
+            <para>HttpClient provides <classname>URIBuilder</classname> utility class to simplify 
+                creation and modification of request URIs.</para>
             <programlisting><![CDATA[
-List<NameValuePair> qparams = new ArrayList<NameValuePair>();
-qparams.add(new BasicNameValuePair("q", "httpclient"));
-qparams.add(new BasicNameValuePair("btnG", "Google Search"));
-qparams.add(new BasicNameValuePair("aq", "f"));
-qparams.add(new BasicNameValuePair("oq", null));
-URI uri = URIUtils.createURI("http", "www.google.com", -1, "/search", 
-    URLEncodedUtils.format(qparams, "UTF-8"), null);
+URIBuilder builder = new URIBuilder();
+builder.setScheme("http").setHost("www.google.com").setPath("/search")
+    .setParameter("q", "httpclient")
+    .setParameter("btnG", "Google Search")
+    .setParameter("aq", "f")
+    .setParameter("oq", "");
+URI uri = builder.build();
 HttpGet httpget = new HttpGet(uri);
 System.out.println(httpget.getURI());
 ]]></programlisting>
@@ -276,19 +265,16 @@ domain=localhost
                     supplied by the creator of the entity.</para>
                 <programlisting><![CDATA[
 StringEntity myEntity = new StringEntity("important message", 
-    "UTF-8");
+   ContentType.create("text/plain", "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);
-]]></programlisting>
+System.out.println(EntityUtils.toByteArray(myEntity).length);]]></programlisting>
                 <para>stdout &gt;</para>
                 <programlisting><![CDATA[
-Content-Type: text/plain; charset=UTF-8
+Content-Type: text/plain; charset=utf-8
 17
-UTF-8
 important message
 17
 ]]></programlisting>
@@ -394,7 +380,7 @@ if (entity != null) {
                 <classname>FileEntity</classname>.</para>
             <programlisting><![CDATA[
 File file = new File("somefile.txt");
-FileEntity entity = new FileEntity(file, "text/plain; charset=\"UTF-8\"");
+FileEntity entity = new FileEntity(file, ContentType.create("text/plain", "UTF-8"));        
 
 HttpPost httppost = new HttpPost("http://localhost/action.do");
 httppost.setEntity(entity);
@@ -405,34 +391,6 @@ httppost.setEntity(entity);
                 self-contained instead of using the generic <classname>InputStreamEntity</classname>.
                     <classname>FileEntity</classname> can be a good starting point.</para>
             <section>
-                <title>Dynamic content entities</title>
-                <para>Often HTTP entities need to be generated dynamically based a particular
-                    execution context. HttpClient provides support for dynamic entities by using
-                    the <classname>EntityTemplate</classname> entity class and
-                        <interfacename>ContentProducer</interfacename> interface. 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 entities created with
-                        <classname>EntityTemplate</classname> are generally self-contained and
-                    repeatable.</para>
-                <programlisting><![CDATA[
-ContentProducer cp = new ContentProducer() {
-    public void writeTo(OutputStream outstream) throws IOException {
-        Writer writer = new OutputStreamWriter(outstream, "UTF-8");
-        writer.write("<response>");
-        writer.write("  <content>");
-        writer.write("    important stuff");
-        writer.write("  </content>");
-        writer.write("</response>");
-        writer.flush();
-    }
-};
-HttpEntity entity = new EntityTemplate(cp);
-HttpPost httppost = new HttpPost("http://localhost/handler.do");
-httppost.setEntity(entity);
-]]></programlisting>
-            </section>
-            <section>
                 <title>HTML forms</title>
                 <para>Many applications need to simulate the process of submitting an
                     HTML form, for instance, in order to log in to a web application or submit input
@@ -659,15 +617,6 @@ Final target: http://www.google.ch
                         target server (i.e. the request has not been fully transmitted to the
                         server).</para>
                 </listitem>
-                <listitem>
-                    <para>HttpClient will automatically retry those methods that have been fully
-                        transmitted to the server, but the server failed to respond with an HTTP
-                        status code (the server simply drops the connection without sending anything
-                        back). In this case it is assumed that the request has not been processed by
-                        the server and the application state has not changed. If this assumption may
-                        not hold true for the web server your application is targeting it is highly
-                        recommended to provide a custom exception handler.</para>
-                </listitem>
             </itemizedlist>
         </section>
         <section>
@@ -688,12 +637,20 @@ HttpRequestRetryHandler myRetryHandler =
             // Do not retry if over max retry count
             return false;
         }
-        if (exception instanceof NoHttpResponseException) {
-            // Retry if the server dropped connection on us
-            return true;
+        if (exception instanceof InterruptedIOException) {
+            // Timeout
+            return false;
+        }
+        if (exception instanceof UnknownHostException) {
+            // Unknown host
+            return false;
+        }
+        if (exception instanceof ConnectException) {
+            // Connection refused
+            return false;
         }
-        if (exception instanceof SSLHandshakeException) {
-            // Do not retry on SSL handshake exception
+        if (exception instanceof SSLException) {
+            // SSL handshake exception
             return false;
         }
         HttpRequest request = (HttpRequest) context.getAttribute(

Modified: httpcomponents/httpclient/trunk/src/docbkx/index.xml
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/src/docbkx/index.xml?rev=1240534&r1=1240533&r2=1240534&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/src/docbkx/index.xml (original)
+++ httpcomponents/httpclient/trunk/src/docbkx/index.xml Sat Feb  4 16:30:30 2012
@@ -66,6 +66,7 @@
     <xi:include href="statemgmt.xml"/>
     <xi:include href="authentication.xml"/>
     <xi:include href="httpagent.xml"/>
+    <xi:include href="fluent.xml"/>
     <xi:include href="caching.xml"/>
     <xi:include href="advanced.xml"/>