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.
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:
Opening the settings tab after selecting your application will yield the 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:
<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
and 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 SpringConnectionFactory
class. It provides a set of methods for creating <a rel=nofollow" target="_blank" href="https://docs.spring.io/spring-social/docs/1.0.3.RELEASE/api/org/springframework/social/connect/Connection.html">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
.
Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!
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:
Upon connecting we're redirected to Facebook, asking us for permission to indeed provide this application with our data:
By selecting "Continue", we authenticate the application and we're redirected to our facebookConnected.html
view.
From here, we can visit our feed:
Visiting our feed shows us some of our latest posts:
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 write 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.