1
<?xml version="1.0" encoding="ISO-8859-1"?>
6
<title>HttpClient Tutorial</title>
7
<author email="adrian@ephox.com">Adrian Sutton</author>
8
<revision>$Id: tutorial.xml,v 1.2.2.3 2004/02/23 23:09:05 olegk Exp $</revision>
12
<section name="Overview">
13
<p>This tutorial is designed to provide a basic overview of how to use
14
<em>HttpClient</em>. When you have completed the tutorial you will have written
15
a simple application that downloads a page using <em>HttpClient</em>.</p>
17
<p>It is assumed that you have an understanding of how to program in
18
Java and are familiar with the development environment you are using.</p>
21
<section name="Getting Ready">
22
<p>The first thing you need to do is get a copy of <em>HttpClient</em> and it's
23
dependencies. Currently the only required dependency is
24
<a href="/commons/logging/">commons-logging</a>. This tutorial was
25
written for <em>HttpClient</em> 2.0 and at a minimum requires 2.0 Alpha
26
2. You will also need JDK 1.2.2 or above.</p>
28
<p>Once you've downloaded <em>HttpClient</em> and commons-logging you'll need to
29
put them on your classpath. There is also an optional dependency on JSSE
30
which is required for HTTPS connections; this is not required for this
34
<section name="Concepts">
35
<p>The general process for using <em>HttpClient</em> consists of a number of
39
<li>Create an instance of <code>HttpClient</code>.</li>
40
<li>Create an instance of one of the methods (GetMethod in this
41
case). The URL to connect to is passed in to the the method
43
<li>Tell <code>HttpClient</code> to execute the method.</li>
44
<li>Read the response.</li>
45
<li>Release the connection.</li>
46
<li>Deal with the response.</li>
49
<p>We'll cover how to perform each of these steps below. Notice that we
50
go through the entire process regardless of whether the server returned
51
an error or not. This is important because HTTP 1.1 allows multiple
52
requests to use the same connection by simply sending the requests one
53
after the other. Obviously, if we don't read the entire response to
54
the first request, the left over data will get in the way of the second
55
response. <em>HttpClient</em> tries to handle this but to avoid problems it is
56
important to always read the entire response and release the connection.</p>
58
<div style="font-style: italic; border: 1px solid #888; margin-left: 7px; margin-right: 7px; margin-top: 1em; margin-bottom: 1px;">
60
It is important to always read the entire
61
response and release the connection regardless of whether the server
62
returned an error or not.
67
<section name="Instantiating HttpClient">
68
<p>The no argument constructor for <code>HttpClient</code> provides a good set of
69
defaults for most situations so that is what we'll use.</p>
71
<source>HttpClient client = new HttpClient();</source>
74
<section name="Creating a Method">
75
<p>The various methods defined by the HTTP specification correspond to
76
the various classes in <em>HttpClient</em> which implement the HttpMethod
77
interface. These classes are all found in the package
78
<code>org.apache.commons.httpclient.methods</code>.</p>
80
<p>We will be using the Get method which is a simple method that simply
81
takes a URL and gets the document the URL points to.</p>
83
<source>HttpMethod method = new GetMethod("http://www.apache.org/");</source>
86
<section name="Execute the Method">
87
<p>The actual execution of the method is performed by calling
88
<code>executeMethod</code> on the client and passing in the method to
89
execute. Since networks connections are unreliable, we also need to deal
90
with any errors that occur.</p>
92
<p>There are two kinds of exceptions that could be thrown by
93
executeMethod, <code>HttpRecoverableException</code> and
94
<code>IOException</code>.</p>
96
<subsection name="HttpRecoverableException">
97
<p>A HttpRecoverableException is thrown when an error occurs that is
98
likely to be a once-off problem. Usually the request will succeed on
99
a second attempt, so retrying the connection is generally
100
recommended. Note that HttpRecoverableException actually extends
101
IOException so you can just ignore it and catch the IOException if
102
your application does not retry the request.</p>
105
<subsection name="IOException">
106
<p>An IOException is thrown when the request cannot be sent at all
107
and retrying the connection is also likely to fail. This may be
108
caused by a number of situations including the server being down,
109
inability to resolve the domain name or the server refusing the
113
<p>The other useful piece of information is the status code that is
114
returned by the server. This code is returned by executeMethod as an
115
int and can be used to determine if the request was successful or not
116
and can sometimes indicate that further action is required by the
117
client such as providing authentication credentials.</p>
121
// We will retry up to 3 times.
122
for (int attempt = 0; statusCode == -1 && attempt < 3; attempt++) {
124
// execute the method.
125
statusCode = client.executeMethod(method);
126
} catch (HttpRecoverableException e) {
127
System.err.println("A recoverable exception occurred,
128
retrying. " + e.getMessage());
129
} catch (IOException e) {
130
System.err.println("Failed to download file.");
135
// Check that we didn't run out of retries.
136
if (statusCode == -1) {
137
System.err.println("Failed to recover from exception.");
143
<section name="Read the Response">
144
<p>It is vital that the response body is always read regardless of the
145
status returned by the server. There are three ways to do this:</p>
148
<li>Call <code>method.getResponseBody()</code>. This will return a
149
byte array containing the data in the response body.</li>
150
<li>Call <code>method.getResponseBodyAsString()</code>. This will
151
return a String containing the response body. Be warned though that
152
the conversion from bytes to a String is done using the default
153
encoding so this method may not be portable across all platforms.</li>
154
<li>Call <code>method.getResponseBodyAsStream()</code> and read the
155
entire contents of the stream then call <code>stream.close()</code>.
156
This method is best if it is possible for a lot of data to be received
157
as it can be buffered to a file or processed as it is read. Be sure to
158
always read the entirety of the data and call close on the stream.</li>
161
<p>For this tutorial we will use <code>getResponseBody()</code> for simplicity.</p>
163
<source>byte[] responseBody = method.getResponseBody();</source>
166
<section name="Release the Connection">
167
<p>This is a crucial step to keep things flowing. We must tell
168
<em>HttpClient</em> that we are done with the connection and that it can now be
169
reused. Without doing this <em>HttpClient</em> will wait indefinitely for a
170
connection to free up so that it can be reused.</p>
172
<source>method.releaseConnection();</source>
175
<section name="Deal with the Repsonse">
176
<p>We've now completed our interaction with <em>HttpClient</em> and can just
177
concentrate on doing what we need to do with the data. In our case,
178
we'll just print it out to the console.</p>
180
<p>It's worth noting that if you were retrieving the response as a stream
181
and processing it as it is read, this step would actually be combined
182
with reading the connection, and when you'd finished processing all the
183
data, you'd then close the input stream and release the connection.</p>
185
<p>Note: We should pay attention to character encodings here instead of
186
just using the system default.</p>
188
<source>System.err.println(new String(responseBody));</source>
191
<section name="Final Source Code">
192
<p>When we put all of that together plus a little bit of glue code we get
193
the program below.</p>
196
import org.apache.commons.httpclient.*;
197
import org.apache.commons.httpclient.methods.*;
200
public class HttpClientTutorial {
202
private static String url = "http://www.apache.org/";
204
public static void main(String[] args) {
205
// Create an instance of HttpClient.
206
HttpClient client = new HttpClient();
208
// Create a method instance.
209
HttpMethod method = new GetMethod(url);
211
// Execute the method.
213
// We will retry up to 3 times.
214
for (int attempt = 0; statusCode == -1 && attempt < 3; attempt++) {
216
// execute the method.
217
statusCode = client.executeMethod(method);
218
} catch (HttpRecoverableException e) {
220
"A recoverable exception occurred, retrying." +
222
} catch (IOException e) {
223
System.err.println("Failed to download file.");
228
// Check that we didn't run out of retries.
229
if (statusCode == -1) {
230
System.err.println("Failed to recover from exception.");
234
// Read the response body.
235
byte[] responseBody = method.getResponseBody();
237
// Release the connection.
238
method.releaseConnection();
240
// Deal with the response.
241
// Use caution: ensure correct character encoding and is not binary data
242
System.err.println(new String(responseBody));