Accessing Twitter with Java using HttpClient

Today I am going to post about making authenticated REST calls using Java and the Jakarta Commons HttpClient library.  I am going to use Twitter as an example.  I originally wanted an example that would allow me to post simultaneously to Facebook, LinkedIn and Twitter, but Twitter is the only one that allows such access without going through unnecessary hoops, so here it is.

The HttpClient library is a very useful library that simplifies the process of making HTTP calls in Java.  The project has been around since 2001, originally as a subproject of Jakarta Comons.

The main reason to use the HttpClient library is that it makes calling authenticated HTTP sources easy.  Making HTTP calls in Java is fairly straightforward now anyway, it gets a little more difficult when authentication is involved.  The HttpClient library makes the whole process somewhat trivial, as this example shows.

Since there are two different types of calls to make, but both utilize the same foundation in HttpClient, I found it useful to create a helper method that actually sets up the authentication and executes the call that is passed to it.

Both the Get and the Post methods extend HttpMethodBase, so that will be the input argument.  It is assumed that the user name and password needed for authentication are attributes of the class this method is in and that they have already been set.

Here is the code for the helper method:

/**
 * Executes an Authenticated HTTP method (Get or Post)
 * @param method - the get or post to execute
 * @throws NullPointerException
 * @throws HttpException
 * @throws IOException
 */
private void executeAuthenticatedMethod(HttpMethodBase method)
  throws NullPointerException, HttpException, IOException {
  if ((twitteruser == null)||(twitterpwd == null)) {
    throw new RuntimeException("User and/or password has not been initialized!");
  }
  HttpClient client = new HttpClient();
  Credentials credentials =
    new UsernamePasswordCredentials(this.getTwitteruser(), this.getTwitterpwd());
  client.getState()
    .setCredentials(new AuthScope(twitterhost, 80, AuthScope.ANY_REALM), credentials);
  HostConfiguration host = client.getHostConfiguration();
  host.setHost(new URI("http://"+twitterhost, true));
  client.executeMethod(host, method);
}

Here you can see that all that is necessary to set up an authenticated call is to create some new credentials and assign them to the State of the client.  To configure the call it is necessary to set up the host by setting the HTTP address of the host, in this case “http://www.twitter.com”.  Finally the call that has been passed in to this method is executed.  The results can be access via the call that was passed in so there is no reason to return anything at this point.

The Get is really simple once this helper method is in place.  To demonstrate the get method, I will use the retrieval of a Friends Time LIne in Twitter.  This is an authenticated call as the post will be.

	/**
	 * Gets the 20 most recent statuses by friends (equivalent to /home on the web)
	 * @return a String representing the XML response.
	 */
	private String getFriendsTimeline() {
		String message = "";
		String url = "/statuses/friends_timeline.xml";
		GetMethod get = new GetMethod(url);
	    try {
	    	executeAuthenticatedMethod(get);
		message = message + get.getResponseBodyAsString();
		} catch (URIException e) {
			message = e.getMessage();
		} catch (NullPointerException e) {
			message = e.getMessage();
		} catch (IOException e) {
			message = e.getMessage();
		} finally {
			get.releaseConnection();
		}
		return message;
	}

Here, to use the get, all we need to do now is create the GetMethod with the correct url and pass it to our helper method to be executed. The response is simply returned as a String, which in this case is simply XML. One item to note, is that after the response has been retrieved, the connection is released. This should happen no matter what the status of the call so that the connection to the host is terminated and the resources are freed up.

The post is almost as simple as the get, the only difference in our call is that for the post we are including a parameter that is the Twitter status message to be posted.

	/**
	 * Update your Twitter Status
	 * @param state
	 * @return
	 */
	private String postStateToTwitter(String status) {
		String url = "/statuses/update.xml";
		String message = "";
		PostMethod post = new PostMethod(url);
		NameValuePair params[] = new NameValuePair[1];
		params[0] = new NameValuePair("status", status);
		post.setRequestBody(params);
		message = "Status:"+post.getStatusText() + " " + message;
	    try {
	    	executeAuthenticatedMethod(post);
		} catch (URIException e) {
			message = e.getMessage();
		} catch (NullPointerException e) {
			message = e.getMessage();
		} catch (IOException e) {
			message = e.getMessage();
		} finally {
			post.releaseConnection();
		}

		return message;
	}

To pass the parameter we use the NameValuePair class in the HttpClient library. Create an array of NameValuePair to set and set the names and values accordingly. In this case the name is “status” and the value is the String called status that is passed to the method. Again, remember to release the connection after the call has been made. For this particular method call we are not interesed in the response body, only that what the status of the call is. After running this, you should get a status of “OK” returned from the call.

It is all pulled together in the TwitterClient.java file which you can download here.

Check out the Twitter API Wiki for more information on the Twitter API.

Check out the HttpClient project home for more information about the HttpClient project.

If you are really bored, you can follow me on Twiiter.

Share/Save/Bookmark

Related posts:

  1. Java Pass By Reference A colleague of mine, sent me this link in regards...
  2. Generate an Java-based Ajax-enabled Web App in 5 Minutes Over the last couple of years there has been a...
  3. Adding Sound to the FlashCard JavaFX Game I finally had a small amount of time to look...
  4. The Dark Side of Frameworks Framework seems to be a pretty hot buzzword these days....
  5. Welcome to Java Hair Please stay tuned for meaningful information and great amounts of...

5 comments

  1. jpswain Mar 29

    Just curious if you tried getting this to work with http-client 4.x (http://hc.apache.org/httpcomponents-client/index.html)
    I have been able to get it work ok with the GET requests on the Twitter API, as well as the POST ones. The problem is that with the POST ones I have to encode the params into the URL myself. Using the methods in the client examples did not work. Just curious.
    Thanks for posting how to do it with the 3.x client!
    Jamie

  2. Robert Nocera Mar 29

    Actually I haven’t tried it with 4.x I was using 3.1 at the time.

  3. jpswain Mar 31

    Ok, I feel silly coming back to answer my own question, but I figured it out, for anyone who might want to use httpclient 4.x:
    The important thing is that your HttpPost must use the BasicHttpParams and can’t have useExpectContinue set to true. This is what caused a 417 Expectation Failed response for me.

    Like this:
    // >> Set Hostname
    hostname = “twitter.com”;
    // >> HttpParams
    HttpParams params = new BasicHttpParams();
    // NOTE This following line cannot set true or you get error 417 Expectation Failed.
    HttpProtocolParams.setUseExpectContinue(params, false);
    HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
    standardHttpPostParams = params;
    // >> AuthScope
    authScope = new AuthScope(hostname, 80);
    // >> Credentials
    credentials = new UsernamePasswordCredentials(username, password);
    // >> Client
    client = new DefaultHttpClient(getStandardPostParams());
    applyCredentials(client);

  4. Robert Nocera Apr 1

    Thanks for that, jpswain, I hadn’t had time to look into it yet.

  1. Useful resource to create twitter application | blogfreakz.com

Leave a reply

You must be logged in to post a comment.