~ubuntu-branches/ubuntu/lucid/commons-httpclient/lucid

« back to all changes in this revision

Viewing changes to docs/tutorial.xml.orig

  • Committer: Bazaar Package Importer
  • Author(s): Barry Hawkins
  • Date: 2005-11-25 13:12:23 UTC
  • Revision ID: james.westby@ubuntu.com-20051125131223-2g7eyo21pqgrohpo
Tags: upstream-2.0.2
ImportĀ upstreamĀ versionĀ 2.0.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?xml version="1.0" encoding="ISO-8859-1"?>
 
2
 
 
3
<document>
 
4
 
 
5
  <properties>
 
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>
 
9
  </properties>
 
10
 
 
11
  <body>
 
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>
 
16
 
 
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>
 
19
    </section>
 
20
 
 
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>
 
27
 
 
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
 
31
      tutorial.</p>
 
32
    </section>
 
33
 
 
34
    <section name="Concepts">
 
35
      <p>The general process for using <em>HttpClient</em> consists of a number of
 
36
      steps:</p>
 
37
 
 
38
      <ol>
 
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
 
42
        constructor.</li>
 
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>
 
47
      </ol>
 
48
 
 
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>
 
57
 
 
58
      <div style="font-style: italic; border: 1px solid #888; margin-left: 7px; margin-right: 7px; margin-top: 1em; margin-bottom: 1px;">
 
59
        <p>
 
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.
 
63
        </p>
 
64
      </div>
 
65
    </section>
 
66
 
 
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>
 
70
 
 
71
      <source>HttpClient client = new HttpClient();</source>
 
72
    </section>
 
73
 
 
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>
 
79
 
 
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>
 
82
 
 
83
      <source>HttpMethod method = new GetMethod("http://www.apache.org/");</source>
 
84
    </section>
 
85
 
 
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>
 
91
 
 
92
      <p>There are two kinds of exceptions that could be thrown by
 
93
      executeMethod, <code>HttpRecoverableException</code> and
 
94
      <code>IOException</code>.</p>
 
95
    
 
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>
 
103
        </subsection>
 
104
          
 
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
 
110
          connection.</p>
 
111
        </subsection>
 
112
 
 
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>
 
118
 
 
119
        <source><![CDATA[
 
120
          int statusCode = -1;
 
121
          // We will retry up to 3 times.
 
122
          for (int attempt = 0; statusCode == -1 && attempt < 3; attempt++) {
 
123
              try {
 
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.");
 
131
                  e.printStackTrace();
 
132
                  System.exit(-1);
 
133
              }
 
134
          }
 
135
          // Check that we didn't run out of retries.
 
136
          if (statusCode == -1) {
 
137
              System.err.println("Failed to recover from exception.");
 
138
              System.exit(-2);
 
139
          }]]>
 
140
        </source>
 
141
    </section> 
 
142
 
 
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>
 
146
 
 
147
      <ul>
 
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>
 
159
      </ul>
 
160
 
 
161
      <p>For this tutorial we will use <code>getResponseBody()</code> for simplicity.</p>
 
162
 
 
163
      <source>byte[] responseBody = method.getResponseBody();</source>
 
164
    </section>
 
165
 
 
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>
 
171
 
 
172
      <source>method.releaseConnection();</source>
 
173
    </section>
 
174
 
 
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>
 
179
 
 
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>
 
184
 
 
185
      <p>Note: We should pay attention to character encodings here instead of
 
186
      just using the system default.</p>
 
187
 
 
188
      <source>System.err.println(new String(responseBody));</source>
 
189
    </section>
 
190
 
 
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>
 
194
 
 
195
      <source><![CDATA[
 
196
        import org.apache.commons.httpclient.*;
 
197
        import org.apache.commons.httpclient.methods.*;
 
198
        import java.io.*;
 
199
 
 
200
        public class HttpClientTutorial {
 
201
          
 
202
          private static String url = "http://www.apache.org/";
 
203
 
 
204
          public static void main(String[] args) {
 
205
            // Create an instance of HttpClient.
 
206
            HttpClient client = new HttpClient();
 
207
 
 
208
            // Create a method instance.
 
209
            HttpMethod method = new GetMethod(url);
 
210
 
 
211
            // Execute the method.
 
212
            int statusCode = -1;
 
213
            // We will retry up to 3 times.
 
214
            for (int attempt = 0; statusCode == -1 && attempt < 3; attempt++) {
 
215
              try {
 
216
                // execute the method.
 
217
                statusCode = client.executeMethod(method);
 
218
              } catch (HttpRecoverableException e) {
 
219
                System.err.println(
 
220
                  "A recoverable exception occurred, retrying." + 
 
221
                  e.getMessage());
 
222
              } catch (IOException e) {
 
223
                System.err.println("Failed to download file.");
 
224
                e.printStackTrace();
 
225
                System.exit(-1);
 
226
              }
 
227
            }
 
228
            // Check that we didn't run out of retries.
 
229
            if (statusCode == -1) {
 
230
              System.err.println("Failed to recover from exception.");
 
231
              System.exit(-2);
 
232
            }
 
233
 
 
234
            // Read the response body.
 
235
            byte[] responseBody = method.getResponseBody();
 
236
 
 
237
            // Release the connection.
 
238
            method.releaseConnection();
 
239
 
 
240
            // Deal with the response.
 
241
            // Use caution: ensure correct character encoding and is not binary data
 
242
            System.err.println(new String(responseBody));
 
243
          }
 
244
        }
 
245
      ]]></source>
 
246
    </section>
 
247
  </body>
 
248
</document>