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 ></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 ></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"/>