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.

6 thoughts on “Spring Social Facebook Application on the Desktop

    • Hi, thanks for replying.

      What do you mean by “try to display the token”?

      You need to copy the url your browser sent you to and paste it in the console. I hope this answers your question. If not, could you elaborate and perhaps rephrase?

  1. Hey, pretty nice and concrete tutorial.

    just a question, do you have found some exception like:

    Exception in thread “main” java.lang.NoSuchMethodError: org.springframework.util.CollectionUtils.unmodifiableMultiValueMap(Lorg/springframework/util/MultiValueMap;)Lorg/springframework/util/MultiValueMap;
    at org.springframework.web.util.UriComponents.(UriComponents.java:100)
    at org.springframework.web.util.UriComponentsBuilder.build(UriComponentsBuilder.java:222)
    at org.springframework.web.util.UriComponentsBuilder.build(UriComponentsBuilder.java:212)
    at org.springframework.web.util.UriTemplate.(UriTemplate.java:70)
    at org.springframework.web.client.RestTemplate$HttpUrlTemplate.(RestTemplate.java:645)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:399)
    at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:279)
    at org.springframework.social.facebook.connect.FacebookOAuth2Template.postForAccessGrant(FacebookOAuth2Template.java:57)
    at org.springframework.social.oauth2.OAuth2Template.exchangeForAccess(OAuth2Template.java:104)
    at com.eamrfid.social.HelloWorld.main(HelloWorld.java:50)

    Looks like if we could not use null in the method exchangeForAccess of OAuth2Operations.

    I tried supplying an empty LinkedMultiValueMap but same result (as expected). The exchangeForAccess java doc say that this last argument should not be encoded, but the exception shows a, not so clear, NoSuchMethodError exception.

    Any idea about the why of that exception?… I wrote the tutorial as is.

    Thanks in advance.

  2. Hello, I solved my issue … it was caused by some dependency in my pom which was using .
    spring 3.0.x …. so I changed all my pom to use latest spring core, social and dependencies.
    That solved my problem.

    Thanks, again, by the example.

    Regards,

  3. Hi! I tried to use the Apache HttpClient implementation to do my requests instead of opening the browser and copy-paste it in the application. But I can’t make it work… It keeps getting a status 200 (instead of the redirect) and saying that I unauthorized.

    Any help?




Leave a Reply