OverviewThis tutorial is designed to provide a basic overview of how to use HttpClient . When you have completed the tutorial you will have written a simple application that downloads a page using HttpClient . It is assumed that you have an understanding of how to program in Java and are familiar with the development environment you are using. Getting ReadyThe first thing you need to do is get a copy of HttpClient and it's dependencies. Currently the only required dependency is commons-logging . This tutorial was written for HttpClient 2.0 and at a minimum requires 2.0 Alpha 2. You will also need JDK 1.2.2 or above. Once you've downloaded HttpClient and commons-logging you'll need to put them on your classpath. There is also an optional dependency on JSSE which is required for HTTPS connections; this is not required for this tutorial. ConceptsThe general process for using HttpClient consists of a number of steps:
We'll cover how to perform each of these steps below. Notice that we go through the entire process re gardless of whether the server returned an error or not. This is important because HTTP 1.1 allows multiple requests to use the same connection by simply sending the requests one after the other. Obviously, if we don't read the entire response to the first request, the left over data will get in the way of the second response. HttpClient tries to handle this but to avoid problems it is important to always read the entire response and release the connection. It is important to always read the entire response and release the connection regardless of whether the server returned an error or not. Instantiating HttpClient
The no argument constructor for
HttpClient client = new HttpClient(); Creating a Method
The various methods defined by the HTTP specification correspond to
the various classes in
HttpClient
which implement the HttpMethod
interface. These classes are all found in the package
We will be using the Get method which is a simple method that simply takes a URL and gets the document the URL points to. HttpMethod method = new GetMethod("http://www.apache.org/"); Execute the Method
The actual execution of the method is performed by calling
There are two kinds
of exceptions that could be thrown by
executeMethod,
HttpRecoverableExceptionA HttpRecoverableException is thrown when an error occurs that is likely to be a once-off problem. Usually the request will succeed on a second attempt, so retrying the connection is generally recommended. Note that HttpRecoverableException actually extends IOException so you can just ignore it and catch the IOException if your application does not retry the request. IOExceptionAn IOException is thrown when the request cannot be sent at all and retrying the connection is also likely to fail. This may be caused by a number of situations including the server being down, inability to resolve the domain name or the server refusing the connection. The other useful piece of information is the status code that is returned by the server. This code is returned by executeMethod as an int and can be used to determine if the request was successful or not and can sometimes indicate that further action is required by the client such as providing authentication credentials. int statusCode = -1; // We will retry up to 3 times. for (int attempt = 0; statusCode == -1 && attempt < 3; attempt++) { try { // execute the method. statusCode = client.executeMethod(method); } catch (HttpRecoverableException e) { System.err.println("A recoverable exception occurred, retrying. " + e.getMessage()); } catch (IOException e) { System.err.println("Failed to download file."); e.printStackTrace(); System.exit(-1); } } // Check that we didn't run out of retries. if (statusCode == -1) { System.err.println("Failed to recover from exception."); System.exit(-2); } Read the ResponseIt is vital that the response body is always read regardless of the status returned by the server. There are three ways to do this:
For this tutorial we will use
byte[] responseBody = method.getResponseBody(); Release the ConnectionThis is a crucial step to keep things flowing. We must tell HttpClient that we are done with the connection and that it can now be reused. Without doing this HttpClient will wait indefinitely for a connection to free up so that it can be reused. method.releaseConnection(); Deal with the RepsonseWe've now completed our interaction with HttpClient and can just concentrate on doing what we need to do with the data. In our case, we'll just print it out to the console. It's worth noting that if you were retrieving the response as a stream and processing it as it is read, this step would actually be combined with reading the connection, and when you'd finished processing all the data, you'd then close the input stream and release the connection. Note: We should pay attention to character encodings here instead of just using the system default. System.err.println(new String(responseBody)); Final Source CodeWhen we put all of that together plus a little bit of glue code we get the program below. import org.apache.commons.httpclient.*; import org.apache.commons.httpclient.methods.*; import java.io.*; public class HttpClientTutorial { private static String url = "http://www.apache.org/"; public static void main(String[] args) { // Create an instance of HttpClient. HttpClient client = new HttpClient(); // Create a method instance. HttpMethod method = new GetMethod(url); // Execute the method. int statusCode = -1; int attempt = 0; // We will retry up to 3 times. while (statusCode == -1 && attempt < 3; attempt++) { try { // execute the method. statusCode = client.executeMethod(method); } catch (HttpRecoverableException e) { System.err.println( "A recoverable exception occurred, retrying." + e.getMessage()); } catch (IOException e) { System.err.println("Failed to download file."); e.printStackTrace(); System.exit(-1); } } // Check that we didn't run out of retries. if (statusCode == -1) { System.err.println("Failed to recover from exception."); System.exit(-2); } // Read the response body. byte[] responseBody = method.getResponseBody(); // Release the connection. method.releaseConnection(); // Deal with the response. // Use caution: ensure correct character encoding and is not binary data System.err.println(new String(responseBody)); } } |