Demo of Twitter Application-Only OAuth Authentication Using Java

Access Twitter Using JavaI found that there was little in the way of examples using Application-Only OAuth for Twitter using Java. So I thought I would put together the basics for those looking for the same thing. This demo example below shows you how to acquire a bearer token and then using that token to issue requests to Twitter’s REST API version 1.1. However, only endpoints that don’t need to have a user account can be used. This means that the demo can primarily use those endpoints which list publicly accessible tweets, lists or user information.

Twitter’s Two Types of Authentication

Twitter features two different types of authentication. The first type is user authentication (OAth Signed) which allows an application to act on behalf of the user, as the user. When it comes to issuing a command, such as creating or editing status tweets, you would need to use this type of authentication. If that is the type of program you need to create, consider reading the Twitter section on obtaining access tokens for this type of access.

The second type of authentication, which this demo shows how to use, is application-only authentication. This type of access doesn’t need a program to login as a specific user. This method is for programs that just need to access public information. Examples of this type of information are tweets and lists in pretty much a read only environment. This authentication scheme is great for widgets, tweet readers, and other projects that don’t need to act on behalf of a specific user.

Before using a specific endpoint URL, be sure to check which type of authentication scheme it needs to use. But the quick way to think about it is to ask yourself “Would I have to login to twitter to do this action?” If the answer is yes, then you know you need the user authentication model.

The Authentication Process

The process for Application only authentication is relatively simple. It goes through the following steps:

  1. Register with Twitter to get a consumer key and consumer secret.
  2. Combine the key and secret together and encode it with a base64 encoding.
  3. Use that new encoded key to ask Twitter for a bearer token.
  4. Get the token back from Twitter, save it and then supply it in the headers of additional requests.

After you have gotten your consumer key and secret, we have to create a function that will take both, meld them together and encode them. But Java doesn’t come with a standard way to encode into base64. For this we decided to use the Apache Commonds Codec to encode the keys. Once you download and add the jar to your project, you can then use the encoder to encode our key and secret.

// Encodes the consumer key and secret to create the basic authorization key
private static String encodeKeys(String consumerKey, String consumerSecret) {
	try {
		String encodedConsumerKey = URLEncoder.encode(consumerKey, "UTF-8");
		String encodedConsumerSecret = URLEncoder.encode(consumerSecret, "UTF-8");
		
		String fullKey = encodedConsumerKey + ":" + encodedConsumerSecret;
		byte[] encodedBytes = Base64.encodeBase64(fullKey.getBytes());
		return new String(encodedBytes);  
	}
	catch (UnsupportedEncodingException e) {
		return new String();
	}
}

Here we take in the key and secret, concatenate them together with a colon and then encode them using our Base64 object we got from the Apache Commons Codec package. Here we encoded them as UTF-8 encoding and return the encoded string. If we get the rare unsupported encoding exception, we will return a blank string.

Now that we have our encoded key (stored in a variable called encodedCredentials) it is time to request our bearer token from Twitter. To do that we are going to open up a secure SSL connection to Twitter’s authentication URL and supply it with the encoded key string in the Authorization header. If everything goes through correctly, it will return the token in the form of a JavaScript Notation (JSON) object. Below is how we are going to do this…

// Constructs the request for requesting a bearer token and returns that token as a string
private static String requestBearerToken(String endPointUrl) throws IOException {
	HttpsURLConnection connection = null;
	String encodedCredentials = encodeKeys("<consumerkey>","<consumersecret>");
		
	try {
		URL url = new URL(endPointUrl); 
		connection = (HttpsURLConnection) url.openConnection();           
		connection.setDoOutput(true);
		connection.setDoInput(true); 
		connection.setRequestMethod("POST"); 
		connection.setRequestProperty("Host", "api.twitter.com");
		connection.setRequestProperty("User-Agent", "Your Program Name");
		connection.setRequestProperty("Authorization", "Basic " + encodedCredentials);
		connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8"); 
		connection.setRequestProperty("Content-Length", "29");
		connection.setUseCaches(false);
			
		writeRequest(connection, "grant_type=client_credentials");
			
		// Parse the JSON response into a JSON mapped object to fetch fields from.
		JSONObject obj = (JSONObject)JSONValue.parse(readResponse(connection));
			
		if (obj != null) {
			String tokenType = (String)obj.get("token_type");
			String token = (String)obj.get("access_token");
		
			return ((tokenType.equals("bearer")) && (token != null)) ? token : "";
		}
		return new String();
	}
	catch (MalformedURLException e) {
		throw new IOException("Invalid endpoint URL specified.", e);
	}
	finally {
		if (connection != null) {
			connection.disconnect();
		}
	}
}

At this point it became clear that we needed to find a way to be able to digest the JSON responses that Twitter is going to give us after we make the request. For this problem we brought in Google’s JSON-Simple package. We had originally considered using Google’s GSon but we needed something that would simply encode the result into an array or object without knowing much about the result’s structure. This is because Twitter makes it clear that the structure changes and some fields may be out of order or simply not existent. This makes it difficult to use GSon which requires casting to specific classes.

So with this code we ask Twitter to give us the bearer token by opening up the connection, posting the appropriate headers through a POST request and in the body specifying client credentials as the grant type. We submit this request to Twitter’s POST oauth2/token endpoint URL. It then replies with the bearer token which we fetch from the object given to us using the JSONValue object (supplied by the JSON-Simple package).

Ok, we now have the bearer token and so we will save this and use it for additional requests. In the function below we are going to ask for the first two tweets supplied by the twitter account @twitterapi.

// Fetches the first tweet from a given user's timeline
private static String fetchTimelineTweet(String endPointUrl) throws IOException {
	HttpsURLConnection connection = null;
				
	try {
		URL url = new URL(endPointUrl); 
		connection = (HttpsURLConnection) url.openConnection();           
		connection.setDoOutput(true);
		connection.setDoInput(true); 
		connection.setRequestMethod("GET"); 
		connection.setRequestProperty("Host", "api.twitter.com");
		connection.setRequestProperty("User-Agent", "Your Program Name");
		connection.setRequestProperty("Authorization", "Bearer " + bearerToken);
		connection.setUseCaches(false);
			
			
		// Parse the JSON response into a JSON mapped object to fetch fields from.
		JSONArray obj = (JSONArray)JSONValue.parse(readResponse(connection));
			
		if (obj != null) {
			String tweet = ((JSONObject)obj.get(0)).get("text").toString();

			return (tweet != null) ? tweet : "";
		}
		return new String();
	}
	catch (MalformedURLException e) {
		throw new IOException("Invalid endpoint URL specified.", e);
	}
	finally {
		if (connection != null) {
			connection.disconnect();
		}
	}
}

In the code above we make another request, this time a GET request, to Twitter using the URL https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=twitterapi&count=2 which will show us two tweets from the twitterapi account. The sample itself just grabs the first tweet however in case you were wondering. It takes the response, converts it to an object that we can get at using standard java.util.map and java.util.list get() method calls. We get at the first item and then access the value for that item’s “text” key and returns it. This is the text of the tweet. If the item is not found, it will return null and in that case we return an empty string.

The last thing we need for this program is some helper functions readResponse() and writeRequest(). I won’t go into these methods much because they are simply stream reading and writing routines that are self explanatory.

// Writes a request to a connection
private static boolean writeRequest(HttpsURLConnection connection, String textBody) {
	try {
		BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream()));
		wr.write(textBody);
		wr.flush();
		wr.close();
			
		return true;
	}
	catch (IOException e) { return false; }
}
	
	
// Reads a response for a given connection and returns it as a string.
private static String readResponse(HttpsURLConnection connection) {
	try {
		StringBuilder str = new StringBuilder();
			
		BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
		String line = "";
		while((line = br.readLine()) != null) {
			str.append(line + System.getProperty("line.separator"));
		}
		return str.toString();
	}
	catch (IOException e) { return new String(); }
}

The Summary

With the encodedKeys() function we took our key and secret and put them together and encoded them. We then took that string, supplied it to Twitter’s oauth2/token endpoint URL via a POST request to get back a bearer token. Once we had the token we saved it and used it in a GET request to @twitterapi’s timeline to get at their tweets. To help us easily process the JSON responses back from twitter we used Google’s JSON-Simple package which took the JSON and built objects we could then use to get at the info.

Given these functions we can easily build more functionality for issuing other requests on behalf of the user as an application. We hope that has proved useful to you and helps you all build great little Twitter apps using Java.

And if you are interested in creating your own little project but don’t know where to start, check out our ebook featuring 200 programming projects, tips to help solve them, reference links and more.

Thanks again for reading! 🙂

About The Author

Martyr2 is the founder of the Coders Lexicon and author of the new ebooks "The Programmers Idea Book" and "Diagnosing the Problem" . He has been a programmer for over 18 years. He works for a hot application development company in Vancouver Canada which service some of the biggest telecoms in the world. He has won numerous awards for his mentoring in software development and contributes regularly to several communities around the web. He is an expert in numerous languages including .NET, PHP, C/C++, Java and more.
  • Maulana Yudhi

    can give me your full example code for this?

    • This is pretty much all the code. I show how to connect to twitter, put together your bearer token and then use it to fetch a timeline tweet. Toss it into a Java test harness app and you are golden.

      • Kaidul Islam Sazal

        Please give some working code. I am facing problem with importing commons-codec 🙁

  • Kaidul Islam Sazal

    Please give the complete source code.

  • André de Kroon

    Don’t know what i am doing wrong. I’m getting a 200/ok message. But the JSON object stays null. So no “token_type” or “access_token” in the response.

  • carlo liwanag

    I needed such service and thanks to this post, I had a great start. But there are some minor details that was not clearly specified (but its in the post).

    So in the method requestBearerToken, we need to pass the twitter api as the endpoint and not the resource url we want to use:

    String twitterApiEndpoint = “https://api.twitter.com/oauth2/token”;

    So use this url in creating the HttpsURLConnection:
    URL url = new URL(twitterApiEndpoint);
    connection = (HttpsURLConnection) url.openConnection();

    After generating the bearerToken, in the method fetchTimelineTweet, this is where you put the endpoint of the timeline:

    https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=&count=50

    Hope this helps.

  • magnetichub

    can you please tell me how can i get more number of tweets?

  • maryam

    this could’ve been done better. no import instructions, many user-defined methods whose source codes are not provided. i thought you wanted to help?!?!

  • Paul Kohler

    Thanks. The example code is well commented and easy to understand. The explanations helped me write a C#/Mono project for university.