| <html><head> |
| <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> |
| <title>Chapter 6. Fluent API</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="HttpClient Tutorial"><link rel="up" href="index.html" title="HttpClient Tutorial"><link rel="prev" href="httpagent.html" title="Chapter 5. HTTP client service"><link rel="next" href="caching.html" title="Chapter 7. HTTP Caching"></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-client-ga/" title="Apache HttpComponents Client"><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 6. Fluent API</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="httpagent.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="caching.html">Next</a></td></tr></table><hr></div><div class="chapter" title="Chapter 6. Fluent API"><div class="titlepage"><div><div><h2 class="title"><a name="fluent"></a>Chapter 6. Fluent API</h2></div></div></div> |
| |
| <div class="section" title="6.1. Easy to use facade API"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d5e1259"></a>6.1. Easy to use facade API</h2></div></div></div> |
| |
| <p> |
| 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. |
| </p> |
| <p>Here are several examples of HTTP requests executed through the HC fluent API</p> |
| <pre class="programlisting"> |
| // Execute a GET with timeout settings and return response content as String. |
| Request.Get("http://somehost/") |
| .connectTimeout(1000) |
| .socketTimeout(1000) |
| .execute().returnContent().asString(); |
| |
| </pre> |
| <pre class="programlisting"> |
| // 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(); |
| |
| </pre> |
| <pre class="programlisting"> |
| // 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")); |
| |
| </pre> |
| <p>One can also use <code class="classname">Executor</code> directly in order to execute requests in |
| a specific security context whereby authentication details are cached and re-used for |
| subsequent requests. |
| </p> |
| <pre class="programlisting"> |
| 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(); |
| |
| </pre> |
| <div class="section" title="6.1.1. Response handling"><div class="titlepage"><div><div><h3 class="title"><a name="d5e1269"></a>6.1.1. Response handling</h3></div></div></div> |
| |
| <p>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 <code class="interfacename">ResponseHandler</code> for HTTP response |
| processing in order to avoid having to buffer content in memory.</p> |
| <pre class="programlisting"> |
| 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); |
| } |
| } |
| |
| }); |
| |
| </pre> |
| </div> |
| <div class="section" title="6.1.2. Asynchronous execution"><div class="titlepage"><div><div><h3 class="title"><a name="d5e1274"></a>6.1.2. Asynchronous execution</h3></div></div></div> |
| |
| <p>The fluent facade API can be used to execute multiple requests asynchronously using |
| background threads. |
| </p> |
| <pre class="programlisting"> |
| 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 |
| |
| </pre> |
| </div> |
| </div> |
| </div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="httpagent.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="caching.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 5. HTTP client service </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 7. HTTP Caching</td></tr></table></div></body></html> |