How to Access the Facebook API with Java and Spring Boot

Overview

Being able to access APIs from major social media platforms can be used as a powerful and useful tool. Fortunately, it's not hard to do so, especially using Spring Boot, and more precisely, the Spring Social module.

Spring Social offers four main projects:

  • Spring Social Core
  • Spring Social Facebook
  • Spring Social Twitter
  • Spring Social LinkedIn

Each of these projects provides tools to communicate with their respective APIs.

In this tutorial, we'll be relying on Spring Social Facebook to make a simple application that authenticates and authorizes a user, and then shows them their own Facebook feed.

Prerequisites

There are two things needed for this project to work.

Spring Boot Application

We'll be starting off with a default state Spring Boot application. Thankfully, using Spring Initializr or even the built-in IntelliJ Idea Spring Initializr plugin, we can easily get a skeleton project to build upon.

Whichever option you choose, select the Web and Thymeleaf dependencies, we'll add the other ones later.

spring initializr

Facebook Developers

Additionally, in order for Spring Social to be able to communicate with the Facebook API, it requires a Facebook Application.

In order to create a Facebook Application, you must have a Facebook Developer account.

Once you've registered, you can add a new application. It requires just a name and a contact email address and looks like this:

facebook developers

Opening the settings tab after selecting your application will yield required information to set-up the connection between Spring Social and your application like, the "App ID" and "App Secret".

Maven Dependencies

Assuming you've correctly set-up your Spring Boot application, we can now add the rest of the needed dependencies.

Your dependency tree should look like this:

<dependencies>  
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>

  <dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.190</version>
  </dependency>

  <dependency>
    <groupId>org.springframework.social</groupId>
    <artifactId>spring-social-facebook</artifactId>
    <version>3.0.0.M1</version>
  </dependency>

  <dependency>
    <groupId>org.springframework.social</groupId>
    <artifactId>spring-social-core</artifactId>
    <version>2.0.0.M2</version>
  </dependency>
  <dependency>
    <groupId>org.springframework.social</groupId>
    <artifactId>spring-social-config</artifactId>
    <version>2.0.0.M2</version>
  </dependency>

  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
  </dependency>
</dependencies>  

A dependency for the H2 Database is included simply because Spring Boot requires a data source, and it's the easiest to just provide one for it.

Accessing the Facebook API

Enabling Facebook

A connection between your Spring application and the Facebook application is required to proceed.

To set up the connection, open up the application.properties file located under src/main.

Input:

spring.social.facebook.appId = // your application ID  
spring.social.facebook.appSecret = // your application secret  

Defining these two properties alerts Spring Social Facebook and it sets up two crucial beans for our application.

  • ConnectController - This class manages the connection flow for the account-to-service-provider and it handles all of the requests regarding Facebook.
  • FacebookConnectionFactory - The Facebook implementation of the Spring ConnectionFactory class. It provides a set of methods for creating Connection instances for Facebook.

Creating a Connection

As mentioned above, the ConnectController is the main workforce in this area. This controller will handle our GET requests when we want to connect to Facebook. It requires just two simple views to work properly - connect/facebookConnect and connect/facebookConnected.

Facebook can be substituted here with any other provider ID, like 'twitter', in which case it would require connect/twitterConnect and a connect/twitterConnected view.

Let's define these views ourselves:

facebookConnect:

<html xmlns:th="www.thymeleaf.org">  
<head>  
    <!-- Bootstrap core CSS -->
    <link th:href="@{/css/bootstrap.min.css}" rel="stylesheet"/>
    <title>Spring Boot Facebook Application</title>
</head>

<body>  
<!-- Page Content -->  
<div class="container">  
    <div class="row">
        <div class="col-lg-12 text-center">
            <h1 class="mt-5">Connect to Facebook:</h1>
            <p class="lead">By clicking connect, you will be asked to authorize the application.</p>

            <form action="/connect/facebook" method="POST">
                <input type="hidden" name="scope" value="user_posts"/>

                <button class="btn btn-default" type="submit">Connect</button>
            </form>
        </div>
    </div>
</div>  
</body>  
</html>  

facebookConnected:

<html xmlns:th="www.thymeleaf.org">  
<head>  
    <!-- Bootstrap core CSS -->
    <link th:href="@{/css/bootstrap.min.css}" rel="stylesheet"/>
    <title>Spring Boot Facebook Application</title>
</head>

<body>  
<!-- Page Content -->  
<div class="container">  
    <div class="row">
        <div class="col-lg-12 text-center">
            <h1 class="mt-5">Connected successfully!</h1>
            <p class="lead">Welcome to facebook!</p>

            <p>You can now browse your own feed <a href="/feed">here</a>.</p>
            <p>You can also see your friend list <a href="/friends">here</a>.</p>
        </div>
    </div>
</div>  
</body>  
</html>  

Once you click "Connect" on the first view, the form will send a POST request for our ConnectController to handle, and the OAuth authorization starts.

Retrieving Facebook Data

With a Facebook connection fully set-up, we can go ahead and write our main controller:

@Controller
public class MainController {  
    private Facebook facebook;
    private ConnectionRepository connectionRepository;

    public MainController(Facebook facebook, ConnectionRepository connectionRepository) {
        this.facebook = facebook;
        this.connectionRepository = connectionRepository;
    }

    @RequestMapping(value = "feed", method = RequestMethod.GET)
    public String feed(Model model) {

        if(connectionRepository.findPrimaryConnection(Facebook.class) == null) {
            return "redirect:/connect/facebook";
        }

        User userProfile = facebook.userOperations().getUserProfile();
        model.addAttribute("userProfile", userProfile);
        PagedList<Post> userFeed = facebook.feedOperations().getFeed();
        model.addAttribute("userFeed", userFeed);
        return "feed";
    }
}

This controller works in a simple fashion. It requires us to inject Facebook and ConnectionRepository into its constructor. The Facebook class provides basic methods for interaction with Facebook, while the ConnectionRepository class, as the name implies, is a data access interface for Connection objects.

The @RequestMapping annotation defines two things - the value and the method:

  • Value - Corresponds to the request parameter we wish to map.
  • Method - Corresponds to the type of the expected HTTP method.

connectionRepository.findPrimaryConnection(Facebook.class) will only be null if the user didn't authorize our application to retrieve data from Facebook. If this is the case, the application simply returns to /connect/facebook.

The User object from the Spring Social Facebook's API is used to store our user's data. This object can contain all of the user's public information, like the first and last name, age range, birthday, hometown, email address etc...

Then we make a PagedList of Posts that corresponds to the user's own feed and add it as a model attribute to our view.

We now need to define the view in which we render this information with Thymeleaf.

feed.html:

<html xmlns:th="www.thymeleaf.org">

<head>  
    <!-- Bootstrap core CSS -->
    <link th:href="@{/css/bootstrap.min.css}" rel="stylesheet"/>
    <title>Spring Boot Facebook Application</title>
</head>  
<body>  
    <div class="container">

        <h3 class="mt-5">Welcome, <span th:text="${userProfile.name}"></span>!</h3>

        <h4 class="mt-5">Facebook Feed:</h4>
        <div class="row">
            <div class="col-lg-12 text-center" th:each="post:${userFeed}" style="border:1px">
                <b class="lead" th:text="${post.from.name}">from</b> posted:
                <p class="lead" th:text="${post.message}">message text</p>
                <img th:if="${post.picture}" th:src="${post.picture}" class="img-thumbnail"/>
                <hr>
            </div>
        </div>
    </div>
</div>  
</body>  
</html>  

Note: Since Facebook version 2.0, the ability to retrieve a Facebook friend list was removed. This functionality is no longer supported by Facebook and trying to get a friend list in Spring will simply return an empty list.

And with that, this application is concluded. Let's run it and see the result.

Application Demo

After deploying the application and going to localhost:8080/connect/facebook we are greeted by our application asking us to connect.

connect

Upon connecting we're redirected to Facebook, asking us for permission to indeed provide this application with our data.

authorize

By selecting "Continue", we authenticate the application and we're redirected to our facebookConnected.html view.

From here, we can visit our feed.

connected

Visiting our feed shows us some of our latest posts:

feed

Additional Functionalities

Spring Social doesn't end there. There are numerous other functionalities that it offers besides checking your feed:

  • AchievementOperations - Provides operations for Facebook achievements.
  • CommentOperations - Provides CRUD operations for comments.
  • EventOperations - Provides CRUD operations for events, as well as invitations.
  • FeedOperations - Retrieving from and posting to a Facebook wall.
  • FriendOperations - Retrieving friend lists.
  • GroupOperations - Retrieve informations from groups (members, details, etc.)
  • LikeOperations - Retrieving and performing likes on posts, pages etc.
  • MediaOperations - Provides CRUD operations for media like photos/videos/albums.
  • OpenGraphOperations - Provides operations for Facebook's OpenGraph API.
  • PageOperations - Provides operations for Facebook pages.
  • SocialContextOperations - Provides operations for a user's social context.
  • TestUserOperations - Provides operations for creating and using test users.
  • UserOperations - Retrieve user information.
  • RestOperations - Used to place an OAuth Authorization header for access tokens sent via requests.

Each of these provide sets of methods for their designated purpose, and collectively, they can be used to build powerful tools.

Covering all of these would be out of scope for this blog, so we'll cover only the most important and useful ones, like posting to walls, reading feeds, and so on.

Retrieving Other Profiles

The same as we did when we retrieved our own data, we can retrieve data from other users too by passing their ID as the parameter.

// Retrieves authenticated user's profile
User profile = facebook.userOperations().getUserProfile();  
// Retrieves the user's profile whose id is 4.
User profile = facebook.userOperations().getUserProfile(4);  

Fun fact: The ID with the numeric value '4' belongs to Mark Zuckerberg and all ID's before this one were test accounts in the early days of Facebook.

Posting Statuses

Posting to your feed is as easy as calling a single method with a String parameter. But keep in mind that you can only post to feeds of users who authenticate the application, and they cannot post to their friend's walls.

You may want to use this to in automated services like IFTT or Buffer.

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

This will simply post a single status with the String that you input.

Another way to post a status is to post a link:

FacebookLink facebookLink = new FacebookLink("link", "name", "caption", "description");  
facebook.feedOperations().post("Posting a link!", facebookLink);  
Posting to a Friend's Feed

This functionality has been removed by Facebook in 2013.

Retrieving a Friend List

This functionality has been removed by Facebook in 2014.

Conclusion

In this tutorial, we took a dive into Spring Social, and more precisely, the Spring Social Facebook project.

We made a Facebook developer account and a Spring Boot application with a connection to our Facebook application.

Afterward, we explored some of the functionalities of the Facebook project in our own, as well as some other functionalities that this API offers.

The source code of this project is available on GitHub.

Author image
About David Landup
Serbia Twitter Github