Java Apache HttpClient REST (RESTful) client examples

I started writing some Java REST (RESTful) clients lately, and in doing so, I've been looking at several different ways to do this, including using the Apache HttpClient project, the Jersey project, Apache CXF, and more.

In this article I share some source code for some simple Java REST clients that use the Apache HttpClient project. The REST client examples I share here are based on the examples on the HttpClient website; I've mostly just tried to make them a little easier to read, and add some additional documentation to them.

Also, I'm just focusing on HTTP GET requests in this article, because I'm writing real-world code to hit the Twitter REST API, and all I need right now are GET requests. But hopefully these examples will make other POST or other RESTful examples easier to read.

Java REST client example 1

This first example shows a combination of these Apache HttpClient classes used to get information from the Yahoo Weather API. That service actually returns information in an RSS format, but if you don't mind parsing that XML, it's an easy way to get weather updates. This REST client uses the following Apache HttpClient classes:

  • DefaultHttpClient
  • HttpHost
  • HttpGet
  • HttpResponse
  • HttpEntity

It also shows how to get all of the headers from the web service you're calling. I wish I could have provided this demo with the OpenSSO demos I wrote a few years ago (see my PHP OpenSSO REST API examples), because the OpenSSO REST API made extensive use of header information. Hopefully you can try this against different URLs where you can examine the header information in more detail.

Here's the source code for this first example class.

package tests;

import org.apache.http.*;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

/**
 * A simple Java REST GET example using the Apache HTTP library.
 * This executes a call against the Yahoo Weather API service, which is
 * actually an RSS service (http://developer.yahoo.com/weather/).
 * 
 * Try this Twitter API URL for another example (it returns JSON results):
 * http://search.twitter.com/search.json?q=%40apple
 * (see this url for more twitter info: https://dev.twitter.com/docs/using-search)
 * 
 * Apache HttpClient: http://hc.apache.org/httpclient-3.x/
 *
 */
public class ApacheHttpRestClient1 {

  public static void main(String[] args) {
    DefaultHttpClient httpclient = new DefaultHttpClient();
    try {
      // specify the host, protocol, and port
      HttpHost target = new HttpHost("weather.yahooapis.com", 80, "http");
      
      // specify the get request
      HttpGet getRequest = new HttpGet("/forecastrss?p=80020&u=f");

      System.out.println("executing request to " + target);

      HttpResponse httpResponse = httpclient.execute(target, getRequest);
      HttpEntity entity = httpResponse.getEntity();

      System.out.println("----------------------------------------");
      System.out.println(httpResponse.getStatusLine());
      Header[] headers = httpResponse.getAllHeaders();
      for (int i = 0; i < headers.length; i++) {
        System.out.println(headers[i]);
      }
      System.out.println("----------------------------------------");

      if (entity != null) {
        System.out.println(EntityUtils.toString(entity));
      }

    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      // When HttpClient instance is no longer needed,
      // shut down the connection manager to ensure
      // immediate deallocation of all system resources
      httpclient.getConnectionManager().shutdown();
    }
  }
}

In all of these examples I thought about getting rid of the try/catch/finally blocks to make the code easier to read, but in my other work with Java network clients, I've found it important to release the network resources in a finally block, so I have left those blocks in the examples.

Java REST client example 2a

As you can see in this next example, this class is based on the Apache HttpClient ClientConnectionRelease example class, though I've added quite a bit of processing ability to this class.

Once again, this REST client example has a large amount of try/catch/finally code, so I've included one version of this code here (which I call version "2a"), and another version below with fewer try/catch/finally blocks and clauses. Here's the source code:

package tests;

import java.io.*;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

/**
 * This example demonstrates an alternative way to call a URL
 * using the Apache HttpClient HttpGet and HttpResponse
 * classes.
 * 
 * I copied the guts of this example from the Apache HttpClient
 * ClientConnectionRelease class, and decided to leave all the
 * try/catch/finally handling in the class. You don't have to catch
 * all the exceptions individually like this, I just left the code
 * as-is to demonstrate all the possible exceptions.
 * 
 * Apache HttpClient: http://hc.apache.org/httpclient-3.x/
 *
*/
public class ApacheHttpRestClient2 {

  public final static void main(String[] args) {
    
    HttpClient httpClient = new DefaultHttpClient();
    try {
      // this twitter call returns json results.
      // see this page for more info: https://dev.twitter.com/docs/using-search
      // http://search.twitter.com/search.json?q=%40apple

      // Example URL 1: this yahoo weather call returns results as an rss (xml) feed
      //HttpGet httpGetRequest = new HttpGet("http://weather.yahooapis.com/forecastrss?p=80020&u=f");
      
      // Example URL 2: this twitter api call returns results in a JSON format
      HttpGet httpGetRequest = new HttpGet("http://search.twitter.com/search.json?q=%40apple");

      // Execute HTTP request
      HttpResponse httpResponse = httpClient.execute(httpGetRequest);

      System.out.println("----------------------------------------");
      System.out.println(httpResponse.getStatusLine());
      System.out.println("----------------------------------------");

      // Get hold of the response entity
      HttpEntity entity = httpResponse.getEntity();

      // If the response does not enclose an entity, there is no need
      // to bother about connection release
      byte[] buffer = new byte[1024];
      if (entity != null) {
        InputStream inputStream = entity.getContent();
        try {
          int bytesRead = 0;
          BufferedInputStream bis = new BufferedInputStream(inputStream);
          while ((bytesRead = bis.read(buffer)) != -1) {
            String chunk = new String(buffer, 0, bytesRead);
            System.out.println(chunk);
          }
        } catch (IOException ioException) {
          // In case of an IOException the connection will be released
          // back to the connection manager automatically
          ioException.printStackTrace();
        } catch (RuntimeException runtimeException) {
          // In case of an unexpected exception you may want to abort
          // the HTTP request in order to shut down the underlying
          // connection immediately.
          httpGetRequest.abort();
          runtimeException.printStackTrace();
        } finally {
          // Closing the input stream will trigger connection release
          try {
            inputStream.close();
          } catch (Exception ignore) {
          }
        }
      }
    } catch (ClientProtocolException e) {
      // thrown by httpClient.execute(httpGetRequest)
      e.printStackTrace();
    } catch (IOException e) {
      // thrown by entity.getContent();
      e.printStackTrace();
    } finally {
      // When HttpClient instance is no longer needed,
      // shut down the connection manager to ensure
      // immediate deallocation of all system resources
      httpClient.getConnectionManager().shutdown();
    }
  }
}

I've tried to document all of these classes fairly well, so I won't discuss them much here. The thing I will say is that this class shows how you can use a complete URL when constructing your HttpGet request. This is easier when you're just calling one web service from one host, while the earlier approach may be better if you're calling many web services from one host, such as from the Twitter API.

Java REST client example 2b

This next example is just a clean-up of the previous REST client, so I won't say much about it, other than to note that I've removed all of the try/catch code except for one block. As you can see, this makes the code much easier to digest.

package tests;

import java.io.*;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

/**
 * This class is the same as the ApacheHttpRestClient2 class, but with
 * fewer try/catch clauses, and fewer comments.
*/
public class ApacheHttpRestClient3 {

  public final static void main(String[] args) {
    
    HttpClient httpClient = new DefaultHttpClient();
    try {
      HttpGet httpGetRequest = new HttpGet("http://search.twitter.com/search.json?q=%40apple");
      HttpResponse httpResponse = httpClient.execute(httpGetRequest);

      System.out.println("----------------------------------------");
      System.out.println(httpResponse.getStatusLine());
      System.out.println("----------------------------------------");

      HttpEntity entity = httpResponse.getEntity();

      byte[] buffer = new byte[1024];
      if (entity != null) {
        InputStream inputStream = entity.getContent();
        try {
          int bytesRead = 0;
          BufferedInputStream bis = new BufferedInputStream(inputStream);
          while ((bytesRead = bis.read(buffer)) != -1) {
            String chunk = new String(buffer, 0, bytesRead);
            System.out.println(chunk);
          }
        } catch (Exception e) {
          e.printStackTrace();
        } finally {
          try { inputStream.close(); } catch (Exception ignore) {}
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      httpClient.getConnectionManager().shutdown();
    }
  }
}

Java REST clients using the Apache HttpClient library

I hope these examples of creating Java REST (RESTful) clients using the Apache HttpClient have been helpful. As mentioned, these examples are heavily based on the Apache HttpClient samples, and I recommend looking at that code for more examples. I've just focused on GET requests in this article, because I'm mostly interested in retrieving basic information from the Twitter API, but if/when I get to POST or other REST client needs, I'll be glad to share that code here as well.