Spring Social Facebook Application on the Desktop

So, you want to access Facebook from your application from a non-web, non-mobile environment? I looked around for a bit and found Spring Social. There was “facebook-java-api”, but I didn’t get very far using it. Spring Social is exactly what it says on the tin: a module in Spring that allows you to easily access the (more popular) social networks. Documentation on how to use it in a non-web environment is pretty scarce, so I decided to throw my working Hello World online.

Things you need before we start:

There also maven support:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
<groupId>net.mymilkedeek</groupId>
 <artifactId>social</artifactId>
 <version>0.0.1-SNAPSHOT</version>
<name>MME Social</name>
<dependencies>
 <dependency>
 <groupId>org.springframework.social</groupId>
 <artifactId>spring-social-core</artifactId>
 <version>1.0.1.RELEASE</version>
 </dependency>
 <dependency>
 <groupId>org.springframework.social</groupId>
 <artifactId>spring-social-facebook</artifactId>
 <version>1.0.1.RELEASE</version>
 </dependency>
 <dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-core</artifactId>
 <version>3.1.0.RELEASE</version>
 </dependency>
 </dependencies></project>

As you can see from the pom.xml: each social network is going to require an added dependency. For this example we’re going to stick with Facebook.

Now, onto the code:

FacebookConnectionFactory connectionFactory = new FacebookConnectionFactory(apiKey, secretKey);
OAuth2Operations oauthOperations = connectionFactory.getOAuthOperations();
 OAuth2Parameters params = new OAuth2Parameters();
 params.setRedirectUri("https://www.facebook.com/dialog/oauth?client_id=" + apiKey + "&amp;redirect_uri=" + redirectUri);
 params.setScope("user_about_me,user_birthday,user_likes,user_status,publish_stream");
String authorizeUrl = oauthOperations.buildAuthorizeUrl( GrantType.AUTHORIZATION_CODE, params);

In this first bit, we are configuring our application. We set our api and secret key and we add a redirect URI, which is provided to us by Facebook. We also set the scope of our program. The scope are the permissions our application will have and what the user will see when he has to allow our application access to his Facebook data.

As you can see, Facebook uses OAuth2. For more information on OAuth, check out various tutorials and articles online.

java.awt.Desktop desktop = java.awt.Desktop.getDesktop();
 if (!desktop.isSupported(java.awt.Desktop.Action.BROWSE)) {
 System.out.println("No browsing allowed...");
 System.exit(1);
 }

 try {
 java.net.URI uri = new java.net.URI(authorizeUrl);
 desktop.browse(uri);
 } catch (Exception e) {
 System.err.println(e.getMessage());
}

Because we have a desktop application, we have to either start a browser and point it to the authorization url or implement a browser into our application. The latter has the benefit of not relying on the user to provide you with the Token, but on the returned url. But, that’s beyond the scope of this application, so we’re just going to have the user copy paste the url into our console.

System.out.println("Token : ");
 Scanner scanner = new Scanner(System.in);
 String input = scanner.next();
 input = input.replace("https://www.facebook.com/connect/login_success.html?code=", "");
System.out.println(input);

If I have to explain this then you’re looking at the wrong tutorial.

AccessGrant accessGrant = oauthOperations.exchangeForAccess(input, redirectUri, null);
Connection<Facebook> connection = connectionFactory.createConnection(accessGrant);
Facebook facebook = connection.getApi();

This is the code of the Facebook application. ¬†We request an Access Token from Facebook and use that to create a Facebook object. The Facebook object will allow you to utilize Facebook’s functions and data. And it will allow us to write “Hello World” to our wall by writing:

facebook.feedOperations().updateStatus("Hello World");

And that’s it. I wanted to post this because I could not find any resource that wasn’t out of date or incorrect.

Things to note:

  • Do not rely on your users to copy paste the authorization tokens. Implement a small browser into your application. This will make it that much more idiot-proof.
  • The Facebook redirect url is “https://www.facebook.com/connect/login_success.html”

Source Code

Now for the entire source code:

HelloWorld.java

package net.mymilkedeek.social;

import java.util.Scanner;

import org.springframework.social.connect.Connection;
import org.springframework.social.facebook.api.Facebook;
import org.springframework.social.facebook.connect.FacebookConnectionFactory;
import org.springframework.social.oauth2.AccessGrant;
import org.springframework.social.oauth2.GrantType;
import org.springframework.social.oauth2.OAuth2Operations;
import org.springframework.social.oauth2.OAuth2Parameters;

public class HelloWorld {
private static final String apiKey = "xxx";
private static final String secretKey = "xxx";
 private static final String redirectUri = "https://www.facebook.com/connect/login_success.html";

 public static void main(String[] args) {
 FacebookConnectionFactory connectionFactory = new FacebookConnectionFactory(apiKey, secretKey);
 OAuth2Operations oauthOperations = connectionFactory.getOAuthOperations();
 OAuth2Parameters params = new OAuth2Parameters();
 params.setRedirectUri("https://www.facebook.com/dialog/oauth?client_id=" + apiKey + "&amp;redirect_uri=" + redirectUri);
 params.setScope("user_about_me,user_birthday,user_likes,user_status,publish_stream");
 String authorizeUrl = oauthOperations.buildAuthorizeUrl(GrantType.AUTHORIZATION_CODE, params);

 java.awt.Desktop desktop = java.awt.Desktop.getDesktop();
 if (!desktop.isSupported(java.awt.Desktop.Action.BROWSE)) {
 System.out.println("No browsing allowed...");
 System.exit(1);
 }

 try {
 java.net.URI uri = new java.net.URI(authorizeUrl);
 desktop.browse(uri);
 } catch (Exception e) {
 System.err.println(e.getMessage());
 }

 System.out.println("Token : ");
 Scanner scanner = new Scanner(System.in);
 String input = scanner.next();
 input = input.replace("https://www.facebook.com/connect/login_success.html?code=", "");
 System.out.println(input);

 AccessGrant accessGrant = oauthOperations.exchangeForAccess(input, redirectUri, null);
 Connection<Facebook> connection = connectionFactory.createConnection(accessGrant);
 Facebook facebook = connection.getApi();

 facebook.feedOperations().updateStatus("Hello World");
 }
}

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
<groupId>net.mymilkedeek</groupId>
 <artifactId>social</artifactId>
 <version>0.0.1-SNAPSHOT</version>
<name>MME Social</name>
 <dependencies>
 <dependency>
 <groupId>org.springframework.social</groupId>
 <artifactId>spring-social-core</artifactId>
 <version>1.0.1.RELEASE</version>
 </dependency>
 <dependency>
 <groupId>org.springframework.social</groupId>
 <artifactId>spring-social-facebook</artifactId>
 <version>1.0.1.RELEASE</version>
 </dependency>
 <dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-core</artifactId>
 <version>3.1.0.RELEASE</version>
 </dependency>
 </dependencies>
</project>

Comments, suggestion and/or corrections are always welcome.